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,233 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Functional-test indicators migrated to contrib.
|
|
3
|
+
|
|
4
|
+
Generated from a single functional strategy module to preserve file-local
|
|
5
|
+
helper functions and constants without cross-test name collisions.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .. import (
|
|
9
|
+
CCI,
|
|
10
|
+
EMA,
|
|
11
|
+
MACD,
|
|
12
|
+
RSI,
|
|
13
|
+
SMA,
|
|
14
|
+
Indicator,
|
|
15
|
+
MinusDirectionalIndicator,
|
|
16
|
+
PlusDirectionalIndicator,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
"BinaryWaveIndicator",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class BinaryWaveIndicator(Indicator):
|
|
25
|
+
"""Weighted indicator that builds a smoothed wave signal from multiple sub-indicators."""
|
|
26
|
+
|
|
27
|
+
lines = (
|
|
28
|
+
"wave",
|
|
29
|
+
"raw",
|
|
30
|
+
)
|
|
31
|
+
params = (
|
|
32
|
+
("weight_ma", 1.0),
|
|
33
|
+
("weight_macd", 1.0),
|
|
34
|
+
("weight_osma", 1.0),
|
|
35
|
+
("weight_cci", 1.0),
|
|
36
|
+
("weight_mom", 1.0),
|
|
37
|
+
("weight_rsi", 1.0),
|
|
38
|
+
("weight_adx", 1.0),
|
|
39
|
+
("ma_period", 13),
|
|
40
|
+
("ma_type", "ema"),
|
|
41
|
+
("fast_macd", 12),
|
|
42
|
+
("slow_macd", 26),
|
|
43
|
+
("signal_macd", 9),
|
|
44
|
+
("cci_period", 14),
|
|
45
|
+
("mom_period", 14),
|
|
46
|
+
("rsi_period", 14),
|
|
47
|
+
("adx_period", 14),
|
|
48
|
+
("smooth_period", 5),
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
def __init__(self):
|
|
52
|
+
"""Instantiate sub-indicators and configure required minimum periods."""
|
|
53
|
+
ma_type = str(self.p.ma_type).lower()
|
|
54
|
+
ma_cls = EMA if ma_type == "ema" else SMA
|
|
55
|
+
self.ma = ma_cls(self.data.close, period=self.p.ma_period)
|
|
56
|
+
self.macd = MACD(
|
|
57
|
+
self.data.close,
|
|
58
|
+
period_me1=self.p.fast_macd,
|
|
59
|
+
period_me2=self.p.slow_macd,
|
|
60
|
+
period_signal=self.p.signal_macd,
|
|
61
|
+
)
|
|
62
|
+
self.cci = CCI(self.data, period=self.p.cci_period)
|
|
63
|
+
self.rsi = RSI(self.data.close, period=self.p.rsi_period)
|
|
64
|
+
self.plus_di = PlusDirectionalIndicator(self.data, period=self.p.adx_period)
|
|
65
|
+
self.minus_di = MinusDirectionalIndicator(self.data, period=self.p.adx_period)
|
|
66
|
+
self.addminperiod(
|
|
67
|
+
max(
|
|
68
|
+
self.p.ma_period,
|
|
69
|
+
self.p.slow_macd + self.p.signal_macd,
|
|
70
|
+
self.p.cci_period,
|
|
71
|
+
self.p.mom_period + 1,
|
|
72
|
+
self.p.rsi_period,
|
|
73
|
+
self.p.adx_period,
|
|
74
|
+
self.p.smooth_period,
|
|
75
|
+
)
|
|
76
|
+
+ 5
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
def _momentum_ratio(self, idx=0):
|
|
80
|
+
base_idx = idx - self.p.mom_period
|
|
81
|
+
base = float(self.data.close[base_idx])
|
|
82
|
+
if base == 0:
|
|
83
|
+
return 100.0
|
|
84
|
+
return float(self.data.close[idx]) / base * 100.0
|
|
85
|
+
|
|
86
|
+
def _score(self):
|
|
87
|
+
score = 0.0
|
|
88
|
+
if self.p.weight_ma > 0:
|
|
89
|
+
if float(self.data.close[0]) > float(self.ma[0]):
|
|
90
|
+
score += self.p.weight_ma
|
|
91
|
+
elif float(self.data.close[0]) < float(self.ma[0]):
|
|
92
|
+
score -= self.p.weight_ma
|
|
93
|
+
if self.p.weight_macd > 0:
|
|
94
|
+
macd_now = float(self.macd.macd[0])
|
|
95
|
+
macd_prev = float(self.macd.macd[-1])
|
|
96
|
+
if macd_now > macd_prev:
|
|
97
|
+
score += self.p.weight_macd
|
|
98
|
+
elif macd_now < macd_prev:
|
|
99
|
+
score -= self.p.weight_macd
|
|
100
|
+
if self.p.weight_osma > 0:
|
|
101
|
+
osma = float(self.macd.macd[0] - self.macd.signal[0])
|
|
102
|
+
if osma > 0:
|
|
103
|
+
score += self.p.weight_osma
|
|
104
|
+
elif osma < 0:
|
|
105
|
+
score -= self.p.weight_osma
|
|
106
|
+
if self.p.weight_cci > 0:
|
|
107
|
+
cci = float(self.cci[0])
|
|
108
|
+
if cci > 0:
|
|
109
|
+
score += self.p.weight_cci
|
|
110
|
+
elif cci < 0:
|
|
111
|
+
score -= self.p.weight_cci
|
|
112
|
+
if self.p.weight_mom > 0:
|
|
113
|
+
mom = self._momentum_ratio(0)
|
|
114
|
+
if mom > 100.0:
|
|
115
|
+
score += self.p.weight_mom
|
|
116
|
+
elif mom < 100.0:
|
|
117
|
+
score -= self.p.weight_mom
|
|
118
|
+
if self.p.weight_rsi > 0:
|
|
119
|
+
rsi = float(self.rsi[0])
|
|
120
|
+
if rsi > 50.0:
|
|
121
|
+
score += self.p.weight_rsi
|
|
122
|
+
elif rsi < 50.0:
|
|
123
|
+
score -= self.p.weight_rsi
|
|
124
|
+
if self.p.weight_adx > 0:
|
|
125
|
+
plus_di = float(self.plus_di[0])
|
|
126
|
+
minus_di = float(self.minus_di[0])
|
|
127
|
+
if plus_di > minus_di:
|
|
128
|
+
score += self.p.weight_adx
|
|
129
|
+
elif plus_di < minus_di:
|
|
130
|
+
score -= self.p.weight_adx
|
|
131
|
+
return score
|
|
132
|
+
|
|
133
|
+
def next(self):
|
|
134
|
+
"""Update raw and smoothed wave values for a single bar."""
|
|
135
|
+
raw = self._score()
|
|
136
|
+
self.lines.raw[0] = raw
|
|
137
|
+
if len(self) == 1:
|
|
138
|
+
self.lines.wave[0] = raw
|
|
139
|
+
return
|
|
140
|
+
alpha = 2.0 / (self.p.smooth_period + 1.0)
|
|
141
|
+
prev_wave = float(self.lines.wave[-1])
|
|
142
|
+
if prev_wave != prev_wave:
|
|
143
|
+
prev_wave = raw
|
|
144
|
+
self.lines.wave[0] = prev_wave + alpha * (raw - prev_wave)
|
|
145
|
+
|
|
146
|
+
def once(self, start, end):
|
|
147
|
+
"""Calculate raw and smoothed wave arrays for a range of bars.
|
|
148
|
+
|
|
149
|
+
Args:
|
|
150
|
+
start: Start index for batch evaluation.
|
|
151
|
+
end: End index (exclusive) for batch evaluation.
|
|
152
|
+
"""
|
|
153
|
+
close_array = self.data.close.array
|
|
154
|
+
ma_array = self.ma.array
|
|
155
|
+
macd_array = self.macd.macd.array
|
|
156
|
+
macd_signal_array = self.macd.signal.array
|
|
157
|
+
cci_array = self.cci.array
|
|
158
|
+
rsi_array = self.rsi.array
|
|
159
|
+
plus_di_array = self.plus_di.array
|
|
160
|
+
minus_di_array = self.minus_di.array
|
|
161
|
+
wave_line = self.lines.wave.array
|
|
162
|
+
raw_line = self.lines.raw.array
|
|
163
|
+
for line in (wave_line, raw_line):
|
|
164
|
+
while len(line) < end:
|
|
165
|
+
line.append(float("nan"))
|
|
166
|
+
|
|
167
|
+
alpha = 2.0 / (self.p.smooth_period + 1.0)
|
|
168
|
+
prev_wave = None
|
|
169
|
+
actual_end = min(
|
|
170
|
+
end,
|
|
171
|
+
len(close_array),
|
|
172
|
+
len(ma_array),
|
|
173
|
+
len(macd_array),
|
|
174
|
+
len(macd_signal_array),
|
|
175
|
+
len(cci_array),
|
|
176
|
+
len(rsi_array),
|
|
177
|
+
len(plus_di_array),
|
|
178
|
+
len(minus_di_array),
|
|
179
|
+
)
|
|
180
|
+
for i in range(start, actual_end):
|
|
181
|
+
score = 0.0
|
|
182
|
+
close = float(close_array[i])
|
|
183
|
+
if self.p.weight_ma > 0:
|
|
184
|
+
ma = float(ma_array[i])
|
|
185
|
+
if close > ma:
|
|
186
|
+
score += self.p.weight_ma
|
|
187
|
+
elif close < ma:
|
|
188
|
+
score -= self.p.weight_ma
|
|
189
|
+
if self.p.weight_macd > 0 and i > 0:
|
|
190
|
+
macd_now = float(macd_array[i])
|
|
191
|
+
macd_prev = float(macd_array[i - 1])
|
|
192
|
+
if macd_now > macd_prev:
|
|
193
|
+
score += self.p.weight_macd
|
|
194
|
+
elif macd_now < macd_prev:
|
|
195
|
+
score -= self.p.weight_macd
|
|
196
|
+
if self.p.weight_osma > 0:
|
|
197
|
+
osma = float(macd_array[i]) - float(macd_signal_array[i])
|
|
198
|
+
if osma > 0:
|
|
199
|
+
score += self.p.weight_osma
|
|
200
|
+
elif osma < 0:
|
|
201
|
+
score -= self.p.weight_osma
|
|
202
|
+
if self.p.weight_cci > 0:
|
|
203
|
+
cci = float(cci_array[i])
|
|
204
|
+
if cci > 0:
|
|
205
|
+
score += self.p.weight_cci
|
|
206
|
+
elif cci < 0:
|
|
207
|
+
score -= self.p.weight_cci
|
|
208
|
+
if self.p.weight_mom > 0:
|
|
209
|
+
base_idx = i - int(self.p.mom_period)
|
|
210
|
+
base = float(close_array[base_idx]) if base_idx >= 0 else 0.0
|
|
211
|
+
mom = close / base * 100.0 if base else 100.0
|
|
212
|
+
if mom > 100.0:
|
|
213
|
+
score += self.p.weight_mom
|
|
214
|
+
elif mom < 100.0:
|
|
215
|
+
score -= self.p.weight_mom
|
|
216
|
+
if self.p.weight_rsi > 0:
|
|
217
|
+
rsi = float(rsi_array[i])
|
|
218
|
+
if rsi > 50.0:
|
|
219
|
+
score += self.p.weight_rsi
|
|
220
|
+
elif rsi < 50.0:
|
|
221
|
+
score -= self.p.weight_rsi
|
|
222
|
+
if self.p.weight_adx > 0:
|
|
223
|
+
plus_di = float(plus_di_array[i])
|
|
224
|
+
minus_di = float(minus_di_array[i])
|
|
225
|
+
if plus_di > minus_di:
|
|
226
|
+
score += self.p.weight_adx
|
|
227
|
+
elif plus_di < minus_di:
|
|
228
|
+
score -= self.p.weight_adx
|
|
229
|
+
|
|
230
|
+
raw_line[i] = score
|
|
231
|
+
wave = score if prev_wave is None else prev_wave + alpha * (score - prev_wave)
|
|
232
|
+
wave_line[i] = wave
|
|
233
|
+
prev_wave = wave
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Functional-test indicators migrated to contrib.
|
|
3
|
+
|
|
4
|
+
Generated from a single functional strategy module to preserve file-local
|
|
5
|
+
helper functions and constants without cross-test name collisions.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .. import (
|
|
9
|
+
ExponentialMovingAverage,
|
|
10
|
+
Indicator,
|
|
11
|
+
SimpleMovingAverage,
|
|
12
|
+
SmoothedMovingAverage,
|
|
13
|
+
WeightedMovingAverage,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"BlauCMomentumIndicator",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def resolve_ma_class(name):
|
|
22
|
+
"""Map a moving-average mode name to a backtrader indicator class.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
name: The MA mode name (e.g. ``sma``, ``ema``, ``smma``, or a MODE_*
|
|
26
|
+
alias).
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
The matching backtrader moving-average indicator class, defaulting to
|
|
30
|
+
the weighted moving average for unrecognised names.
|
|
31
|
+
"""
|
|
32
|
+
mode = str(name).lower()
|
|
33
|
+
if mode in {"mode_sma", "sma"}:
|
|
34
|
+
return SimpleMovingAverage
|
|
35
|
+
if mode in {
|
|
36
|
+
"mode_ema",
|
|
37
|
+
"ema",
|
|
38
|
+
"mode_jjma",
|
|
39
|
+
"jjma",
|
|
40
|
+
"mode_jurx",
|
|
41
|
+
"jurx",
|
|
42
|
+
"mode_parma",
|
|
43
|
+
"parma",
|
|
44
|
+
"mode_t3",
|
|
45
|
+
"t3",
|
|
46
|
+
"mode_vidya",
|
|
47
|
+
"vidya",
|
|
48
|
+
"mode_ama",
|
|
49
|
+
"ama",
|
|
50
|
+
}:
|
|
51
|
+
return ExponentialMovingAverage
|
|
52
|
+
if mode in {"mode_smma", "smma"}:
|
|
53
|
+
return SmoothedMovingAverage
|
|
54
|
+
return WeightedMovingAverage
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def resolve_price_line(data, mode):
|
|
58
|
+
"""Map a price mode name to the corresponding feed price line.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
data: The data feed whose OHLC lines are referenced.
|
|
62
|
+
mode: The price mode name (e.g. ``close``, ``median``, ``typical``,
|
|
63
|
+
``weighted``).
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
The selected price line or derived price expression, defaulting to the
|
|
67
|
+
close for unrecognised modes.
|
|
68
|
+
"""
|
|
69
|
+
price_mode = str(mode).lower()
|
|
70
|
+
if price_mode in {"price_close", "close"}:
|
|
71
|
+
return data.close
|
|
72
|
+
if price_mode in {"price_open", "open"}:
|
|
73
|
+
return data.open
|
|
74
|
+
if price_mode in {"price_high", "high"}:
|
|
75
|
+
return data.high
|
|
76
|
+
if price_mode in {"price_low", "low"}:
|
|
77
|
+
return data.low
|
|
78
|
+
if price_mode in {"price_median", "median"}:
|
|
79
|
+
return (data.high + data.low) / 2.0
|
|
80
|
+
if price_mode in {"price_typical", "typical"}:
|
|
81
|
+
return (data.high + data.low + data.close) / 3.0
|
|
82
|
+
if price_mode in {"price_weighted", "weighted"}:
|
|
83
|
+
return (2.0 * data.close + data.high + data.low) / 4.0
|
|
84
|
+
if price_mode in {"price_simpl", "simpl"}:
|
|
85
|
+
return (data.open + data.close) / 2.0
|
|
86
|
+
if price_mode in {"price_quarter", "quarter"}:
|
|
87
|
+
return (data.high + data.low + data.open + data.close) / 4.0
|
|
88
|
+
return data.close
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class BlauCMomentumIndicator(Indicator):
|
|
92
|
+
"""Blau composite momentum: triple-smoothed price-difference oscillator."""
|
|
93
|
+
|
|
94
|
+
lines = ("value",)
|
|
95
|
+
params = (
|
|
96
|
+
("xma_method", "ema"),
|
|
97
|
+
("xlength", 1),
|
|
98
|
+
("xlength1", 20),
|
|
99
|
+
("xlength2", 5),
|
|
100
|
+
("xlength3", 3),
|
|
101
|
+
("xphase", 15),
|
|
102
|
+
("ipc1", "price_close"),
|
|
103
|
+
("ipc2", "price_open"),
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
def __init__(self):
|
|
107
|
+
"""Build the price difference, triple-smooth it, and set the min period."""
|
|
108
|
+
ma_cls = resolve_ma_class(self.p.xma_method)
|
|
109
|
+
price1 = resolve_price_line(self.data, self.p.ipc1)
|
|
110
|
+
price2 = resolve_price_line(self.data, self.p.ipc2)
|
|
111
|
+
mom = price1 - price2(-max(0, int(self.p.xlength) - 1))
|
|
112
|
+
xmom = ma_cls(mom, period=max(1, int(self.p.xlength1)))
|
|
113
|
+
xxmom = ma_cls(xmom, period=max(1, int(self.p.xlength2)))
|
|
114
|
+
xxxmom = ma_cls(xxmom, period=max(1, int(self.p.xlength3)))
|
|
115
|
+
self._momentum = xxxmom
|
|
116
|
+
self.lines.value = 100.0 * xxxmom
|
|
117
|
+
self.addminperiod(
|
|
118
|
+
int(self.p.xlength)
|
|
119
|
+
+ int(self.p.xlength1)
|
|
120
|
+
+ int(self.p.xlength2)
|
|
121
|
+
+ int(self.p.xlength3)
|
|
122
|
+
+ 5
|
|
123
|
+
)
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Functional-test indicators migrated to contrib.
|
|
3
|
+
|
|
4
|
+
Generated from a single functional strategy module to preserve file-local
|
|
5
|
+
helper functions and constants without cross-test name collisions.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .. import (
|
|
9
|
+
ExponentialMovingAverage,
|
|
10
|
+
Indicator,
|
|
11
|
+
SimpleMovingAverage,
|
|
12
|
+
SmoothedMovingAverage,
|
|
13
|
+
WeightedMovingAverage,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"BlauCMIIndicator",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def resolve_ma_class(name):
|
|
22
|
+
"""Resolve a moving-average name string to a Backtrader indicator class.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
name: Method token from strategy config.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
Backtrader moving average class.
|
|
29
|
+
"""
|
|
30
|
+
mode = str(name).lower()
|
|
31
|
+
if mode in {"mode_sma", "sma"}:
|
|
32
|
+
return SimpleMovingAverage
|
|
33
|
+
if mode in {
|
|
34
|
+
"mode_ema",
|
|
35
|
+
"ema",
|
|
36
|
+
"mode_jjma",
|
|
37
|
+
"jjma",
|
|
38
|
+
"mode_jurx",
|
|
39
|
+
"jurx",
|
|
40
|
+
"mode_parma",
|
|
41
|
+
"parma",
|
|
42
|
+
"mode_t3",
|
|
43
|
+
"t3",
|
|
44
|
+
"mode_vidya",
|
|
45
|
+
"vidya",
|
|
46
|
+
"mode_ama",
|
|
47
|
+
"ama",
|
|
48
|
+
}:
|
|
49
|
+
return ExponentialMovingAverage
|
|
50
|
+
if mode in {"mode_smma", "smma"}:
|
|
51
|
+
return SmoothedMovingAverage
|
|
52
|
+
return WeightedMovingAverage
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def resolve_price_line(data, mode):
|
|
56
|
+
"""Resolve a price selector token into a Backtrader line for arithmetic usage.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
data: Backtrader data feed.
|
|
60
|
+
mode: Price selector string.
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
Data feed line for the selected price.
|
|
64
|
+
"""
|
|
65
|
+
price_mode = str(mode).lower()
|
|
66
|
+
if price_mode in {"price_close", "close"}:
|
|
67
|
+
return data.close
|
|
68
|
+
if price_mode in {"price_open", "open"}:
|
|
69
|
+
return data.open
|
|
70
|
+
if price_mode in {"price_high", "high"}:
|
|
71
|
+
return data.high
|
|
72
|
+
if price_mode in {"price_low", "low"}:
|
|
73
|
+
return data.low
|
|
74
|
+
if price_mode in {"price_median", "median"}:
|
|
75
|
+
return (data.high + data.low) / 2.0
|
|
76
|
+
if price_mode in {"price_typical", "typical"}:
|
|
77
|
+
return (data.high + data.low + data.close) / 3.0
|
|
78
|
+
if price_mode in {"price_weighted", "weighted"}:
|
|
79
|
+
return (2.0 * data.close + data.high + data.low) / 4.0
|
|
80
|
+
if price_mode in {"price_simpl", "simpl"}:
|
|
81
|
+
return (data.open + data.close) / 2.0
|
|
82
|
+
if price_mode in {"price_quarter", "quarter"}:
|
|
83
|
+
return (data.high + data.low + data.open + data.close) / 4.0
|
|
84
|
+
return data.close
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class BlauCMIIndicator(Indicator):
|
|
88
|
+
"""Compute the CMI oscillator from nested moving averages of momentum."""
|
|
89
|
+
|
|
90
|
+
lines = ("value",)
|
|
91
|
+
params = (
|
|
92
|
+
("xma_method", "ema"),
|
|
93
|
+
("xlength", 1),
|
|
94
|
+
("xlength1", 20),
|
|
95
|
+
("xlength2", 5),
|
|
96
|
+
("xlength3", 3),
|
|
97
|
+
("xphase", 15),
|
|
98
|
+
("ipc1", "price_close"),
|
|
99
|
+
("ipc2", "price_open"),
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
def __init__(self):
|
|
103
|
+
"""Set up numerator/denominator moving averages for oscillator output."""
|
|
104
|
+
ma_cls = resolve_ma_class(self.p.xma_method)
|
|
105
|
+
price1 = resolve_price_line(self.data, self.p.ipc1)
|
|
106
|
+
price2 = resolve_price_line(self.data, self.p.ipc2)
|
|
107
|
+
mom = price1 - price2(-max(0, int(self.p.xlength) - 1))
|
|
108
|
+
abs_mom = abs(mom)
|
|
109
|
+
xmom = ma_cls(mom, period=max(1, int(self.p.xlength1)))
|
|
110
|
+
xabsmom = ma_cls(abs_mom, period=max(1, int(self.p.xlength1)))
|
|
111
|
+
xxmom = ma_cls(xmom, period=max(1, int(self.p.xlength2)))
|
|
112
|
+
xxabsmom = ma_cls(xabsmom, period=max(1, int(self.p.xlength2)))
|
|
113
|
+
xxxmom = ma_cls(xxmom, period=max(1, int(self.p.xlength3)))
|
|
114
|
+
xxxabsmom = ma_cls(xxabsmom, period=max(1, int(self.p.xlength3)))
|
|
115
|
+
self._numerator = xxxmom
|
|
116
|
+
self._denominator = xxxabsmom
|
|
117
|
+
self.addminperiod(
|
|
118
|
+
int(self.p.xlength1)
|
|
119
|
+
+ int(self.p.xlength2)
|
|
120
|
+
+ int(self.p.xlength3)
|
|
121
|
+
+ int(self.p.xlength)
|
|
122
|
+
+ 5
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
def next(self):
|
|
126
|
+
"""Populate the indicator value on a per-bar basis."""
|
|
127
|
+
den = float(self._denominator[0])
|
|
128
|
+
self.lines.value[0] = 100.0 * float(self._numerator[0]) / den if den else 0.0
|
|
129
|
+
|
|
130
|
+
def once(self, start, end):
|
|
131
|
+
"""Compute indicator values in a vectorized range for Backtrader backfills."""
|
|
132
|
+
numerator = self._numerator.array
|
|
133
|
+
denominator = self._denominator.array
|
|
134
|
+
value_line = self.lines.value.array
|
|
135
|
+
while len(value_line) < end:
|
|
136
|
+
value_line.append(float("nan"))
|
|
137
|
+
|
|
138
|
+
actual_end = min(end, len(numerator), len(denominator))
|
|
139
|
+
for i in range(start, actual_end):
|
|
140
|
+
den = float(denominator[i])
|
|
141
|
+
value_line[i] = 100.0 * float(numerator[i]) / den if den else 0.0
|
|
@@ -0,0 +1,76 @@
|
|
|
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 backtrader.functions as btfunc
|
|
9
|
+
|
|
10
|
+
from .. import (
|
|
11
|
+
EMA,
|
|
12
|
+
Highest,
|
|
13
|
+
Indicator,
|
|
14
|
+
Lowest,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
"BlauCSI",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _price_series(data, mode):
|
|
23
|
+
key = str(mode).lower()
|
|
24
|
+
if key in ("1", "close", "price_close"):
|
|
25
|
+
return data.close
|
|
26
|
+
if key in ("2", "open", "price_open"):
|
|
27
|
+
return data.open
|
|
28
|
+
if key in ("3", "high", "price_high"):
|
|
29
|
+
return data.high
|
|
30
|
+
if key in ("4", "low", "price_low"):
|
|
31
|
+
return data.low
|
|
32
|
+
if key in ("5", "median", "price_median"):
|
|
33
|
+
return (data.high + data.low) / 2.0
|
|
34
|
+
if key in ("6", "typical", "price_typical"):
|
|
35
|
+
return (data.high + data.low + data.close) / 3.0
|
|
36
|
+
if key in ("7", "weighted", "price_weighted"):
|
|
37
|
+
return (data.high + data.low + data.close + data.close) / 4.0
|
|
38
|
+
if key in ("8", "simple", "price_simpl"):
|
|
39
|
+
return (data.open + data.close) / 2.0
|
|
40
|
+
if key in ("9", "quarter", "price_quarter"):
|
|
41
|
+
return (data.high + data.low + data.open + data.close) / 4.0
|
|
42
|
+
return data.close
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class BlauCSI(Indicator):
|
|
46
|
+
"""Blau CSI indicator built from smoothed momentum vs. range."""
|
|
47
|
+
|
|
48
|
+
lines = ("main",)
|
|
49
|
+
params = (
|
|
50
|
+
("xma_method", "ema"),
|
|
51
|
+
("xlength", 1),
|
|
52
|
+
("xlength1", 20),
|
|
53
|
+
("xlength2", 5),
|
|
54
|
+
("xlength3", 3),
|
|
55
|
+
("ipc1", "close"),
|
|
56
|
+
("ipc2", "open"),
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
def __init__(self):
|
|
60
|
+
"""Initialize smoothed momentum and price-range lines for CSI output."""
|
|
61
|
+
shift = max(int(self.p.xlength) - 1, 0)
|
|
62
|
+
price1 = _price_series(self.data, self.p.ipc1)
|
|
63
|
+
price2 = _price_series(self.data, self.p.ipc2)
|
|
64
|
+
mom = price1 - price2(-shift)
|
|
65
|
+
price_range = Highest(self.data.high, period=max(int(self.p.xlength), 1)) - Lowest(
|
|
66
|
+
self.data.low, period=max(int(self.p.xlength), 1)
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
xmom = EMA(mom, period=int(self.p.xlength1))
|
|
70
|
+
xrange = EMA(price_range, period=int(self.p.xlength1))
|
|
71
|
+
xxmom = EMA(xmom, period=int(self.p.xlength2))
|
|
72
|
+
xxrange = EMA(xrange, period=int(self.p.xlength2))
|
|
73
|
+
xxxmom = EMA(xxmom, period=int(self.p.xlength3))
|
|
74
|
+
xxxrange = EMA(xxrange, period=int(self.p.xlength3))
|
|
75
|
+
|
|
76
|
+
self.l.main = btfunc.DivByZero(100.0 * xxxmom, xxxrange, zero=0.0)
|
|
@@ -0,0 +1,53 @@
|
|
|
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 backtrader.functions as btfunc
|
|
9
|
+
|
|
10
|
+
from .. import (
|
|
11
|
+
EMA,
|
|
12
|
+
Indicator,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"BlauErgodic",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class BlauErgodic(Indicator):
|
|
21
|
+
"""Blau Ergodic oscillator: triple-smoothed normalised momentum.
|
|
22
|
+
|
|
23
|
+
Price momentum and its absolute value are each triple-smoothed with EMAs;
|
|
24
|
+
the main line is 100 times their ratio (guarded against division by zero).
|
|
25
|
+
The signal line is an EMA of the main line, and spread is their difference.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
lines = ("main", "signal", "spread")
|
|
29
|
+
params = (
|
|
30
|
+
("xlength", 2),
|
|
31
|
+
("xlength1", 20),
|
|
32
|
+
("xlength2", 5),
|
|
33
|
+
("xlength3", 3),
|
|
34
|
+
("xlength4", 3),
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
def __init__(self):
|
|
38
|
+
"""Build the triple-EMA momentum chain for main, signal and spread."""
|
|
39
|
+
shift = max(int(self.p.xlength) - 1, 1)
|
|
40
|
+
momentum = self.data.close - self.data.close(-shift)
|
|
41
|
+
abs_momentum = abs(momentum)
|
|
42
|
+
|
|
43
|
+
xmom = EMA(momentum, period=int(self.p.xlength1))
|
|
44
|
+
xxmom = EMA(xmom, period=int(self.p.xlength2))
|
|
45
|
+
xxxmom = EMA(xxmom, period=int(self.p.xlength3))
|
|
46
|
+
|
|
47
|
+
xabsmom = EMA(abs_momentum, period=int(self.p.xlength1))
|
|
48
|
+
xxabsmom = EMA(xabsmom, period=int(self.p.xlength2))
|
|
49
|
+
xxxabsmom = EMA(xxabsmom, period=int(self.p.xlength3))
|
|
50
|
+
|
|
51
|
+
self.l.main = btfunc.DivByZero(100.0 * xxxmom, xxxabsmom, zero=0.0)
|
|
52
|
+
self.l.signal = EMA(self.l.main, period=int(self.p.xlength4))
|
|
53
|
+
self.l.spread = self.l.main - self.l.signal
|
|
@@ -0,0 +1,72 @@
|
|
|
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 backtrader.functions as btfunc
|
|
9
|
+
|
|
10
|
+
from .. import (
|
|
11
|
+
EMA,
|
|
12
|
+
Highest,
|
|
13
|
+
Indicator,
|
|
14
|
+
Lowest,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
"BlauTStochI",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _price_series(data, mode):
|
|
23
|
+
key = str(mode).lower()
|
|
24
|
+
if key in ("1", "close", "price_close"):
|
|
25
|
+
return data.close
|
|
26
|
+
if key in ("2", "open", "price_open"):
|
|
27
|
+
return data.open
|
|
28
|
+
if key in ("3", "high", "price_high"):
|
|
29
|
+
return data.high
|
|
30
|
+
if key in ("4", "low", "price_low"):
|
|
31
|
+
return data.low
|
|
32
|
+
if key in ("5", "median", "price_median"):
|
|
33
|
+
return (data.high + data.low) / 2.0
|
|
34
|
+
if key in ("6", "typical", "price_typical"):
|
|
35
|
+
return (data.high + data.low + data.close) / 3.0
|
|
36
|
+
if key in ("7", "weighted", "price_weighted"):
|
|
37
|
+
return (data.high + data.low + data.close + data.close) / 4.0
|
|
38
|
+
if key in ("8", "simple", "price_simpl"):
|
|
39
|
+
return (data.open + data.close) / 2.0
|
|
40
|
+
if key in ("9", "quarter", "price_quarter"):
|
|
41
|
+
return (data.high + data.low + data.open + data.close) / 4.0
|
|
42
|
+
return data.close
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class BlauTStochI(Indicator):
|
|
46
|
+
"""Indicator generating a smoothed Blau T-Stoch histogram."""
|
|
47
|
+
|
|
48
|
+
lines = ("hist",)
|
|
49
|
+
params = (
|
|
50
|
+
("xlength", 20),
|
|
51
|
+
("xlength1", 5),
|
|
52
|
+
("xlength2", 3),
|
|
53
|
+
("xlength3", 8),
|
|
54
|
+
("ipc", "close"),
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
def __init__(self):
|
|
58
|
+
"""Build EMA-smoothed numerator and denominator terms for histogram output."""
|
|
59
|
+
price = _price_series(self.data, self.p.ipc)
|
|
60
|
+
hh = Highest(self.data.high, period=int(self.p.xlength))
|
|
61
|
+
ll = Lowest(self.data.low, period=int(self.p.xlength))
|
|
62
|
+
stoch = price - ll
|
|
63
|
+
range_line = hh - ll
|
|
64
|
+
|
|
65
|
+
xstoch = EMA(stoch, period=int(self.p.xlength1))
|
|
66
|
+
xrange = EMA(range_line, period=int(self.p.xlength1))
|
|
67
|
+
xxstoch = EMA(xstoch, period=int(self.p.xlength2))
|
|
68
|
+
xxrange = EMA(xrange, period=int(self.p.xlength2))
|
|
69
|
+
xxxstoch = EMA(xxstoch, period=int(self.p.xlength3))
|
|
70
|
+
xxxrange = EMA(xxrange, period=int(self.p.xlength3))
|
|
71
|
+
|
|
72
|
+
self.l.hist = btfunc.DivByZero(100.0 * xxxstoch, xxxrange, zero=0.0) - 50.0
|