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,200 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Plot Formatters Module - Custom formatters for matplotlib plots.
|
|
3
|
+
|
|
4
|
+
This module provides custom formatters for matplotlib charts used in backtrader
|
|
5
|
+
plotting, including volume formatters and date formatters that work with
|
|
6
|
+
backtrader's internal date representation.
|
|
7
|
+
|
|
8
|
+
Classes:
|
|
9
|
+
MyVolFormatter: Custom formatter for volume axis with K/M/B suffixes.
|
|
10
|
+
MyDateFormatter: Custom formatter for date axis.
|
|
11
|
+
|
|
12
|
+
Functions:
|
|
13
|
+
patch_locator: Patch date locator with custom date limits.
|
|
14
|
+
patch_formatter: Patch date formatter with custom date handling.
|
|
15
|
+
getlocator: Create and patch date locator and formatter.
|
|
16
|
+
|
|
17
|
+
Example:
|
|
18
|
+
>>> from backtrader.plot.formatters import MyVolFormatter, MyDateFormatter
|
|
19
|
+
>>> vol_fmt = MyVolFormatter(volmax=1000000)
|
|
20
|
+
>>> date_fmt = MyDateFormatter(dates, fmt='%Y-%m-%d')
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
import matplotlib.dates as mdates
|
|
24
|
+
import matplotlib.ticker as mplticker
|
|
25
|
+
|
|
26
|
+
from ..utils import num2date
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class MyVolFormatter(mplticker.Formatter):
|
|
30
|
+
"""Custom formatter for volume axis labels with magnitude suffixes.
|
|
31
|
+
|
|
32
|
+
This formatter formats volume values with appropriate suffixes (K, M, B, T, P)
|
|
33
|
+
based on the maximum volume value. For example, volumes in the thousands
|
|
34
|
+
will be displayed with 'K' suffix, millions with 'M' suffix, etc.
|
|
35
|
+
|
|
36
|
+
Attributes:
|
|
37
|
+
Suffixes: List of suffixes for different magnitudes.
|
|
38
|
+
|
|
39
|
+
Example:
|
|
40
|
+
>>> formatter = MyVolFormatter(volmax=1500000)
|
|
41
|
+
>>> label = formatter(1000000, 0)
|
|
42
|
+
>>> print(label)
|
|
43
|
+
1M
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
Suffixes = ["", "K", "M", "G", "T", "P"]
|
|
47
|
+
|
|
48
|
+
def __init__(self, volmax):
|
|
49
|
+
"""Initialize the volume formatter.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
volmax: Maximum volume value to be displayed. This determines
|
|
53
|
+
the appropriate suffix and divisor for formatting.
|
|
54
|
+
"""
|
|
55
|
+
self.volmax = volmax
|
|
56
|
+
magnitude = 0
|
|
57
|
+
self.divisor = 1.0
|
|
58
|
+
while abs(volmax / self.divisor) >= 1000:
|
|
59
|
+
magnitude += 1
|
|
60
|
+
self.divisor *= 1000.0
|
|
61
|
+
|
|
62
|
+
self.suffix = self.Suffixes[magnitude]
|
|
63
|
+
|
|
64
|
+
def __call__(self, y, pos=0):
|
|
65
|
+
"""Return the label for time x at position pos"""
|
|
66
|
+
|
|
67
|
+
if y > self.volmax * 1.20:
|
|
68
|
+
return ""
|
|
69
|
+
|
|
70
|
+
y = int(y / self.divisor)
|
|
71
|
+
return "%d%s" % (y, self.suffix)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class MyDateFormatter(mplticker.Formatter):
|
|
75
|
+
"""Custom formatter for date axis labels.
|
|
76
|
+
|
|
77
|
+
This formatter formats dates using backtrader's internal date representation
|
|
78
|
+
and displays them with the specified format string. It handles index-based
|
|
79
|
+
date lookups and ensures valid index bounds.
|
|
80
|
+
|
|
81
|
+
Example:
|
|
82
|
+
>>> formatter = MyDateFormatter(dates, fmt='%Y-%m-%d')
|
|
83
|
+
>>> label = formatter(100, 0)
|
|
84
|
+
>>> print(label)
|
|
85
|
+
2020-01-15
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
def __init__(self, dates, fmt="%Y-%m-%d"):
|
|
89
|
+
"""Initialize the date formatter.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
dates: Array or sequence of dates in backtrader's internal format.
|
|
93
|
+
fmt: strftime-compatible format string for date display.
|
|
94
|
+
Defaults to '%Y-%m-%d'.
|
|
95
|
+
"""
|
|
96
|
+
self.dates = dates
|
|
97
|
+
self.lendates = len(dates)
|
|
98
|
+
self.fmt = fmt
|
|
99
|
+
|
|
100
|
+
def __call__(self, x, pos=0):
|
|
101
|
+
"""Return the label for time x at position pos"""
|
|
102
|
+
ind = int(round(x))
|
|
103
|
+
if ind >= self.lendates:
|
|
104
|
+
ind = self.lendates - 1
|
|
105
|
+
|
|
106
|
+
if ind < 0:
|
|
107
|
+
ind = 0
|
|
108
|
+
|
|
109
|
+
return num2date(self.dates[ind]).strftime(self.fmt)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def patch_locator(locator, xdates):
|
|
113
|
+
"""Patch a date locator with custom date limit conversion methods.
|
|
114
|
+
|
|
115
|
+
This function patches the locator's datalim_to_dt and viewlim_to_dt methods
|
|
116
|
+
to work with backtrader's internal date array (xdates) instead of using
|
|
117
|
+
matplotlib's default date conversion.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
locator: matplotlib date locator instance to patch.
|
|
121
|
+
xdates: Array of dates in backtrader's internal format.
|
|
122
|
+
"""
|
|
123
|
+
|
|
124
|
+
def _patched_datalim_to_dt(self):
|
|
125
|
+
dmin, dmax = self.axis.get_data_interval()
|
|
126
|
+
|
|
127
|
+
# proxy access to xdates
|
|
128
|
+
dmin, dmax = xdates[int(dmin)], xdates[min(int(dmax), len(xdates) - 1)]
|
|
129
|
+
|
|
130
|
+
a, b = num2date(dmin, self.tz), num2date(dmax, self.tz)
|
|
131
|
+
return a, b
|
|
132
|
+
|
|
133
|
+
def _patched_viewlim_to_dt(self):
|
|
134
|
+
vmin, vmax = self.axis.get_view_interval()
|
|
135
|
+
|
|
136
|
+
# proxy access to xdates
|
|
137
|
+
vmin, vmax = xdates[int(vmin)], xdates[min(int(vmax), len(xdates) - 1)]
|
|
138
|
+
a, b = num2date(vmin, self.tz), num2date(vmax, self.tz)
|
|
139
|
+
return a, b
|
|
140
|
+
|
|
141
|
+
# patch the instance with a bound method
|
|
142
|
+
bound_datalim = _patched_datalim_to_dt.__get__(locator, locator.__class__)
|
|
143
|
+
locator.datalim_to_dt = bound_datalim
|
|
144
|
+
|
|
145
|
+
# patch the instance with a bound method
|
|
146
|
+
bound_viewlim = _patched_viewlim_to_dt.__get__(locator, locator.__class__)
|
|
147
|
+
locator.viewlim_to_dt = bound_viewlim
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def patch_formatter(formatter, xdates):
|
|
151
|
+
"""Patch a date formatter with custom date formatting logic.
|
|
152
|
+
|
|
153
|
+
This function patches the formatter's __call__ method to work with
|
|
154
|
+
backtrader's internal date array (xdates) for index-based date lookups.
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
formatter: matplotlib date formatter instance to patch.
|
|
158
|
+
xdates: Array of dates in backtrader's internal format.
|
|
159
|
+
"""
|
|
160
|
+
|
|
161
|
+
def newcall(self, x, pos=0):
|
|
162
|
+
if False and x < 0: # noqa: SIM223 # intentionally-disabled upstream guard
|
|
163
|
+
raise ValueError(
|
|
164
|
+
"DateFormatter found a value of x=0, which is "
|
|
165
|
+
"an illegal date. This usually occurs because "
|
|
166
|
+
"you have not informed the axis that it is "
|
|
167
|
+
"plotting dates, e.g., with ax.xaxis_date()"
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
x = xdates[int(x)]
|
|
171
|
+
dt = num2date(x, self.tz)
|
|
172
|
+
return self.strftime(dt, self.fmt)
|
|
173
|
+
|
|
174
|
+
bound_call = newcall.__get__(formatter, formatter.__class__)
|
|
175
|
+
formatter.__call__ = bound_call
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def getlocator(xdates, numticks=5, tz=None):
|
|
179
|
+
"""Create a patched date locator and formatter for backtrader plots.
|
|
180
|
+
|
|
181
|
+
This function creates matplotlib date locator and formatter instances
|
|
182
|
+
patched to work with backtrader's internal date representation.
|
|
183
|
+
|
|
184
|
+
Args:
|
|
185
|
+
xdates: Array of dates in backtrader's internal format.
|
|
186
|
+
numticks: Target number of ticks on the axis. Defaults to 5.
|
|
187
|
+
tz: Timezone for date conversion. Defaults to None (local timezone).
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
A tuple of (locator, formatter) where:
|
|
191
|
+
- locator: Patched matplotlib date locator instance.
|
|
192
|
+
- formatter: Patched matplotlib date formatter instance.
|
|
193
|
+
"""
|
|
194
|
+
span = xdates[-1] - xdates[0]
|
|
195
|
+
|
|
196
|
+
locator, formatter = mdates.date_ticker_factory(span=span, tz=tz, numticks=numticks)
|
|
197
|
+
|
|
198
|
+
patch_locator(locator, xdates)
|
|
199
|
+
patch_formatter(formatter, xdates)
|
|
200
|
+
return locator, formatter
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Redefine/Override matplotlib locators to make them work with index base x-axis
|
|
5
|
+
which can be converted from/to dates
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import datetime
|
|
9
|
+
import warnings
|
|
10
|
+
|
|
11
|
+
import numpy as np
|
|
12
|
+
from dateutil.relativedelta import relativedelta
|
|
13
|
+
from matplotlib.dates import (
|
|
14
|
+
HOURS_PER_DAY,
|
|
15
|
+
MIN_PER_HOUR,
|
|
16
|
+
MONTHS_PER_YEAR,
|
|
17
|
+
)
|
|
18
|
+
from matplotlib.dates import AutoDateFormatter as ADFormatter
|
|
19
|
+
from matplotlib.dates import AutoDateLocator as ADLocator
|
|
20
|
+
from matplotlib.dates import MicrosecondLocator
|
|
21
|
+
from matplotlib.dates import RRuleLocator as RRLocator
|
|
22
|
+
from matplotlib.dates import num2date, rrulewrapper
|
|
23
|
+
|
|
24
|
+
from ..utils.log_message import get_logger, throttled_warning
|
|
25
|
+
|
|
26
|
+
logger = get_logger(__name__)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _idx2dt(idx, dates, tz):
|
|
30
|
+
"""Convert an index to a datetime object.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
idx: Index value or datetime.date object.
|
|
34
|
+
dates: Array of date values.
|
|
35
|
+
tz: Timezone to use for conversion.
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
datetime.datetime: The corresponding datetime object.
|
|
39
|
+
"""
|
|
40
|
+
if isinstance(idx, datetime.date):
|
|
41
|
+
return idx
|
|
42
|
+
|
|
43
|
+
ldates = len(dates)
|
|
44
|
+
|
|
45
|
+
idx = int(round(idx))
|
|
46
|
+
if idx >= ldates:
|
|
47
|
+
idx = ldates - 1
|
|
48
|
+
if idx < 0:
|
|
49
|
+
idx = 0
|
|
50
|
+
|
|
51
|
+
return num2date(dates[idx], tz)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class RRuleLocator(RRLocator):
|
|
55
|
+
"""Locator for date-based ticks using rrules.
|
|
56
|
+
|
|
57
|
+
This locator extends matplotlib's RRuleLocator to work with index-based
|
|
58
|
+
x-axis that can be converted from/to dates. It handles the conversion
|
|
59
|
+
between data indices and datetime objects.
|
|
60
|
+
|
|
61
|
+
Attributes:
|
|
62
|
+
_dates: Array of date values for index conversion.
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
def __init__(self, dates, o, tz=None):
|
|
66
|
+
"""Initialize the RRuleLocator.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
dates: Array of date values for index conversion.
|
|
70
|
+
o: RRule object defining the tick frequency and rules.
|
|
71
|
+
tz: Timezone to use for datetime conversion. Defaults to None.
|
|
72
|
+
"""
|
|
73
|
+
self._dates = dates
|
|
74
|
+
super().__init__(o, tz)
|
|
75
|
+
|
|
76
|
+
def datalim_to_dt(self):
|
|
77
|
+
"""Convert an axis data interval to datetime objects.
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
tuple: A pair of datetime objects representing the data limits.
|
|
81
|
+
"""
|
|
82
|
+
dmin, dmax = self.axis.get_data_interval()
|
|
83
|
+
if dmin > dmax:
|
|
84
|
+
dmin, dmax = dmax, dmin
|
|
85
|
+
|
|
86
|
+
return (_idx2dt(dmin, self._dates, self.tz), _idx2dt(dmax, self._dates, self.tz))
|
|
87
|
+
|
|
88
|
+
def viewlim_to_dt(self):
|
|
89
|
+
"""Convert the view interval to datetime objects.
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
tuple: A pair of datetime objects representing the view limits.
|
|
93
|
+
"""
|
|
94
|
+
vmin, vmax = self.axis.get_view_interval()
|
|
95
|
+
if vmin > vmax:
|
|
96
|
+
vmin, vmax = vmax, vmin
|
|
97
|
+
|
|
98
|
+
return (_idx2dt(vmin, self._dates, self.tz), _idx2dt(vmax, self._dates, self.tz))
|
|
99
|
+
|
|
100
|
+
def tick_values(self, vmin, vmax):
|
|
101
|
+
"""Return the tick values for the given range.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
vmin: Minimum value of the range.
|
|
105
|
+
vmax: Maximum value of the range.
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
list: List of indices corresponding to tick positions.
|
|
109
|
+
"""
|
|
110
|
+
import bisect
|
|
111
|
+
|
|
112
|
+
dtnums = super().tick_values(vmin, vmax)
|
|
113
|
+
return [bisect.bisect_left(self._dates, x) for x in dtnums]
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class AutoDateLocator(ADLocator):
|
|
117
|
+
"""Locator for automatic date-based tick positioning.
|
|
118
|
+
|
|
119
|
+
This locator extends matplotlib's AutoDateLocator to work with index-based
|
|
120
|
+
x-axis that can be converted from/to dates. It automatically selects the
|
|
121
|
+
appropriate tick frequency based on the date range.
|
|
122
|
+
|
|
123
|
+
Attributes:
|
|
124
|
+
_dates: Array of date values for index conversion.
|
|
125
|
+
"""
|
|
126
|
+
|
|
127
|
+
def __init__(self, dates, *args, **kwargs):
|
|
128
|
+
"""Initialize the AutoDateLocator.
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
dates: Array of date values for index conversion.
|
|
132
|
+
*args: Additional positional arguments passed to parent class.
|
|
133
|
+
**kwargs: Additional keyword arguments passed to parent class.
|
|
134
|
+
"""
|
|
135
|
+
self._dates = dates
|
|
136
|
+
super().__init__(*args, **kwargs)
|
|
137
|
+
|
|
138
|
+
def datalim_to_dt(self):
|
|
139
|
+
"""Convert an axis data interval to datetime objects.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
tuple: A pair of datetime objects representing the data limits.
|
|
143
|
+
"""
|
|
144
|
+
dmin, dmax = self.axis.get_data_interval()
|
|
145
|
+
if dmin > dmax:
|
|
146
|
+
dmin, dmax = dmax, dmin
|
|
147
|
+
|
|
148
|
+
return (_idx2dt(dmin, self._dates, self.tz), _idx2dt(dmax, self._dates, self.tz))
|
|
149
|
+
|
|
150
|
+
def viewlim_to_dt(self):
|
|
151
|
+
"""Convert the view interval to datetime objects.
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
tuple: A pair of datetime objects representing the view limits.
|
|
155
|
+
"""
|
|
156
|
+
vmin, vmax = self.axis.get_view_interval()
|
|
157
|
+
if vmin > vmax:
|
|
158
|
+
vmin, vmax = vmax, vmin
|
|
159
|
+
|
|
160
|
+
return (_idx2dt(vmin, self._dates, self.tz), _idx2dt(vmax, self._dates, self.tz))
|
|
161
|
+
|
|
162
|
+
def tick_values(self, vmin, vmax):
|
|
163
|
+
"""Return the tick values for the given range.
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
vmin: Minimum value of the range.
|
|
167
|
+
vmax: Maximum value of the range.
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
list: List of indices corresponding to tick positions.
|
|
171
|
+
"""
|
|
172
|
+
import bisect
|
|
173
|
+
|
|
174
|
+
dtnums = super().tick_values(vmin, vmax)
|
|
175
|
+
return [bisect.bisect_left(self._dates, x) for x in dtnums]
|
|
176
|
+
|
|
177
|
+
def get_locator(self, dmin, dmax):
|
|
178
|
+
"""Pick the best locator based on a distance.
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
dmin: Minimum datetime value.
|
|
182
|
+
dmax: Maximum datetime value.
|
|
183
|
+
|
|
184
|
+
Returns:
|
|
185
|
+
matplotlib.ticker.Locator: The appropriate locator for the date range.
|
|
186
|
+
"""
|
|
187
|
+
delta = relativedelta(dmax, dmin)
|
|
188
|
+
tdelta = dmax - dmin
|
|
189
|
+
|
|
190
|
+
# take absolute difference
|
|
191
|
+
if dmin > dmax:
|
|
192
|
+
delta = -delta
|
|
193
|
+
tdelta = -tdelta
|
|
194
|
+
|
|
195
|
+
# The following uses a mix of calls to relativedelta and timedelta
|
|
196
|
+
# methods because there is incomplete overlap in the functionality of
|
|
197
|
+
# these similar functions, and it's best to avoid doing our own math
|
|
198
|
+
# whenever possible.
|
|
199
|
+
numYears = float(delta.years)
|
|
200
|
+
numMonths = (numYears * MONTHS_PER_YEAR) + delta.months
|
|
201
|
+
numDays = tdelta.days # Avoids estimates of days/month, days/year
|
|
202
|
+
numHours = (numDays * HOURS_PER_DAY) + delta.hours
|
|
203
|
+
numMinutes = (numHours * MIN_PER_HOUR) + delta.minutes
|
|
204
|
+
numSeconds = np.floor(tdelta.total_seconds())
|
|
205
|
+
numMicroseconds = np.floor(tdelta.total_seconds() * 1e6)
|
|
206
|
+
|
|
207
|
+
nums = [numYears, numMonths, numDays, numHours, numMinutes, numSeconds, numMicroseconds]
|
|
208
|
+
|
|
209
|
+
use_rrule_locator = [True] * 6 + [False]
|
|
210
|
+
|
|
211
|
+
# Default setting of bymonth, etc. to pass to rrule
|
|
212
|
+
# [unused (for year), bymonth, bymonthday, byhour, byminute,
|
|
213
|
+
# bysecond, unused (for microseconds)]
|
|
214
|
+
byranges = [None, 1, 1, 0, 0, 0, None]
|
|
215
|
+
|
|
216
|
+
usemicro = False # use as a flag to avoid raising an exception
|
|
217
|
+
|
|
218
|
+
# Loop over all the frequencies and try to find one that gives at
|
|
219
|
+
# least a minticks tick positions. Once this is found, look for
|
|
220
|
+
# an interval from a list specific to that frequency that gives no
|
|
221
|
+
# more than maxticks tick positions. Also, set up some ranges
|
|
222
|
+
# (bymonth, etc.) as appropriate to be passed to rrulewrapper.
|
|
223
|
+
for i, (freq, num) in enumerate(zip(self._freqs, nums)):
|
|
224
|
+
# If this particular frequency doesn't give enough ticks, continue
|
|
225
|
+
if num < self.minticks:
|
|
226
|
+
# Since we're not using this particular frequency, set
|
|
227
|
+
# the corresponding by_ to None so the rrule can act as
|
|
228
|
+
# appropriate
|
|
229
|
+
byranges[i] = None
|
|
230
|
+
continue
|
|
231
|
+
|
|
232
|
+
# Find the first available interval that doesn't give too many
|
|
233
|
+
# ticks
|
|
234
|
+
for interval in self.intervald[freq]:
|
|
235
|
+
if num <= interval * (self.maxticks[freq] - 1):
|
|
236
|
+
break
|
|
237
|
+
else:
|
|
238
|
+
# We went through the whole loop without breaking, default to
|
|
239
|
+
# the last interval in the list and raise a warning
|
|
240
|
+
warnings.warn(
|
|
241
|
+
"AutoDateLocator was unable to pick an "
|
|
242
|
+
"appropriate interval for this date range. "
|
|
243
|
+
"It may be necessary to add an interval value "
|
|
244
|
+
"to the AutoDateLocator's intervald dictionary."
|
|
245
|
+
" Defaulting to {}.".format(interval)
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
# Set some parameters as appropriate
|
|
249
|
+
self._freq = freq
|
|
250
|
+
|
|
251
|
+
if self._byranges[i] and self.interval_multiples:
|
|
252
|
+
byranges[i] = self._byranges[i][::interval]
|
|
253
|
+
interval = 1
|
|
254
|
+
else:
|
|
255
|
+
byranges[i] = self._byranges[i]
|
|
256
|
+
|
|
257
|
+
# We found what frequency to use
|
|
258
|
+
break
|
|
259
|
+
else:
|
|
260
|
+
if False:
|
|
261
|
+
raise ValueError("No sensible date limit could be found in the AutoDateLocator.")
|
|
262
|
+
usemicro = True
|
|
263
|
+
|
|
264
|
+
if not usemicro and use_rrule_locator[i]:
|
|
265
|
+
_, bymonth, bymonthday, byhour, byminute, bysecond, _ = byranges
|
|
266
|
+
|
|
267
|
+
rrule = rrulewrapper(
|
|
268
|
+
self._freq,
|
|
269
|
+
interval=interval,
|
|
270
|
+
dtstart=dmin,
|
|
271
|
+
until=dmax,
|
|
272
|
+
bymonth=bymonth,
|
|
273
|
+
bymonthday=bymonthday,
|
|
274
|
+
byhour=byhour,
|
|
275
|
+
byminute=byminute,
|
|
276
|
+
bysecond=bysecond,
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
locator = RRuleLocator(self._dates, rrule, self.tz)
|
|
280
|
+
else:
|
|
281
|
+
if usemicro:
|
|
282
|
+
interval = 1 # not set because the for else: was met
|
|
283
|
+
locator = MicrosecondLocator(interval, tz=self.tz)
|
|
284
|
+
|
|
285
|
+
locator.set_axis(self.axis)
|
|
286
|
+
try:
|
|
287
|
+
# try for matplotlib < 3.6.0
|
|
288
|
+
locator.set_view_interval(*self.axis.get_view_interval())
|
|
289
|
+
locator.set_data_interval(*self.axis.get_data_interval())
|
|
290
|
+
except Exception:
|
|
291
|
+
throttled_warning(
|
|
292
|
+
logger,
|
|
293
|
+
"plot.locator.legacy_interval_api_fallback",
|
|
294
|
+
"AutoDateLocator legacy interval API unavailable; using axis interval fallback",
|
|
295
|
+
exc_info=False,
|
|
296
|
+
)
|
|
297
|
+
try:
|
|
298
|
+
# try for matplotlib >= 3.6.0
|
|
299
|
+
self.axis.set_view_interval(*self.axis.get_view_interval())
|
|
300
|
+
self.axis.set_data_interval(*self.axis.get_data_interval())
|
|
301
|
+
locator.set_axis(self.axis)
|
|
302
|
+
except Exception:
|
|
303
|
+
throttled_warning(
|
|
304
|
+
logger,
|
|
305
|
+
"plot.locator.axis_interval_sync_recovery",
|
|
306
|
+
"AutoDateLocator axis interval synchronization failed; retaining locator fallback",
|
|
307
|
+
exc_info=False,
|
|
308
|
+
)
|
|
309
|
+
return locator
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
class AutoDateFormatter(ADFormatter):
|
|
313
|
+
"""Formatter for automatic date-based tick labels.
|
|
314
|
+
|
|
315
|
+
This formatter extends matplotlib's AutoDateFormatter to work with
|
|
316
|
+
index-based x-axis that can be converted from/to dates. It automatically
|
|
317
|
+
formats date labels based on the tick frequency.
|
|
318
|
+
|
|
319
|
+
Attributes:
|
|
320
|
+
_dates: Array of date values for index conversion.
|
|
321
|
+
"""
|
|
322
|
+
|
|
323
|
+
def __init__(self, dates, locator, tz=None, defaultfmt="%Y-%m-%d"):
|
|
324
|
+
"""Initialize the AutoDateFormatter.
|
|
325
|
+
|
|
326
|
+
Args:
|
|
327
|
+
dates: Array of date values for index conversion.
|
|
328
|
+
locator: The locator instance to use for tick positioning.
|
|
329
|
+
tz: Timezone to use for datetime conversion. Defaults to None.
|
|
330
|
+
defaultfmt: Default format string for dates. Defaults to "%Y-%m-%d".
|
|
331
|
+
"""
|
|
332
|
+
self._dates = dates
|
|
333
|
+
super().__init__(locator, tz, defaultfmt)
|
|
334
|
+
|
|
335
|
+
def __call__(self, x, pos=None):
|
|
336
|
+
"""Return the label for time x at position pos.
|
|
337
|
+
|
|
338
|
+
Args:
|
|
339
|
+
x: The index value to convert to a date label.
|
|
340
|
+
pos: The position of the tick. Defaults to None.
|
|
341
|
+
|
|
342
|
+
Returns:
|
|
343
|
+
str: The formatted date label.
|
|
344
|
+
"""
|
|
345
|
+
x = int(round(x))
|
|
346
|
+
ldates = len(self._dates)
|
|
347
|
+
if x >= ldates:
|
|
348
|
+
x = ldates - 1
|
|
349
|
+
|
|
350
|
+
if x < 0:
|
|
351
|
+
x = 0
|
|
352
|
+
|
|
353
|
+
return super()
|