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,57 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Functional-test indicators migrated to contrib.
|
|
3
|
+
|
|
4
|
+
Generated from a single functional strategy module to preserve file-local
|
|
5
|
+
helper functions and constants without cross-test name collisions.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .. import Indicator
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"LaguerrePlusDiProxy",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class LaguerrePlusDiProxy(Indicator):
|
|
16
|
+
"""Laguerre-style +DI proxy normalized to the 0..1 range.
|
|
17
|
+
|
|
18
|
+
Approximates the directional-movement balance used by the original EA by
|
|
19
|
+
computing positive/negative directional movement and true range over the
|
|
20
|
+
lookback period and emitting the normalized +DI share.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
lines = ("value",)
|
|
24
|
+
params = (("period", 14),)
|
|
25
|
+
|
|
26
|
+
def __init__(self):
|
|
27
|
+
"""Set the minimum period required before emitting values."""
|
|
28
|
+
self.addminperiod(self.p.period + 3)
|
|
29
|
+
|
|
30
|
+
def next(self):
|
|
31
|
+
"""Compute the normalized +DI ratio for the current bar."""
|
|
32
|
+
pdm_vals = []
|
|
33
|
+
mdm_vals = []
|
|
34
|
+
tr_vals = []
|
|
35
|
+
for idx in range(self.p.period):
|
|
36
|
+
high0 = float(self.data.high[-idx])
|
|
37
|
+
high1 = float(self.data.high[-idx - 1])
|
|
38
|
+
low0 = float(self.data.low[-idx])
|
|
39
|
+
low1 = float(self.data.low[-idx - 1])
|
|
40
|
+
close1 = float(self.data.close[-idx - 1])
|
|
41
|
+
up_move = high0 - high1
|
|
42
|
+
down_move = low1 - low0
|
|
43
|
+
pdm = up_move if up_move > down_move and up_move > 0 else 0.0
|
|
44
|
+
mdm = down_move if down_move > up_move and down_move > 0 else 0.0
|
|
45
|
+
tr = max(high0 - low0, abs(high0 - close1), abs(low0 - close1))
|
|
46
|
+
pdm_vals.append(pdm)
|
|
47
|
+
mdm_vals.append(mdm)
|
|
48
|
+
tr_vals.append(tr)
|
|
49
|
+
tr_sum = sum(tr_vals)
|
|
50
|
+
if tr_sum <= 1e-12:
|
|
51
|
+
self.lines.value[0] = 0.5
|
|
52
|
+
return
|
|
53
|
+
pdi = 100.0 * sum(pdm_vals) / tr_sum
|
|
54
|
+
mdi = 100.0 * sum(mdm_vals) / tr_sum
|
|
55
|
+
denom = pdi + mdi
|
|
56
|
+
ratio = 0.5 if denom <= 1e-12 else pdi / denom
|
|
57
|
+
self.lines.value[0] = max(0.0, min(1.0, ratio))
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Functional-test indicators migrated to contrib.
|
|
3
|
+
|
|
4
|
+
Generated from a single functional strategy module to preserve file-local
|
|
5
|
+
helper functions and constants without cross-test name collisions.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .. import Indicator
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"LaguerreRocIndicator",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class LaguerreRocIndicator(Indicator):
|
|
16
|
+
"""Laguerre ROC indicator emitting value, midline, and color."""
|
|
17
|
+
|
|
18
|
+
lines = ("lroc", "midline", "color")
|
|
19
|
+
params = (
|
|
20
|
+
("vperiod", 5),
|
|
21
|
+
("gamma", 0.5),
|
|
22
|
+
("up_level", 0.75),
|
|
23
|
+
("dn_level", 0.25),
|
|
24
|
+
("point", 0.01),
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
def __init__(self):
|
|
28
|
+
"""Initialize rolling state and warm-up period."""
|
|
29
|
+
self.addminperiod(int(self.p.vperiod) + 4)
|
|
30
|
+
self._initialized = False
|
|
31
|
+
self._l0 = self._l1 = self._l2 = self._l3 = None
|
|
32
|
+
|
|
33
|
+
def next(self):
|
|
34
|
+
"""Calculate laguerre recursive values and output normalized ROC color."""
|
|
35
|
+
if len(self.data) <= int(self.p.vperiod):
|
|
36
|
+
self.lines.lroc[0] = 0.5
|
|
37
|
+
self.lines.midline[0] = 0.5
|
|
38
|
+
self.lines.color[0] = 2
|
|
39
|
+
return
|
|
40
|
+
reference = float(self.data.close[-int(self.p.vperiod)])
|
|
41
|
+
if reference == 0:
|
|
42
|
+
roc = float(self.p.point)
|
|
43
|
+
else:
|
|
44
|
+
roc = (float(self.data.close[0]) - reference) / reference + float(self.p.point)
|
|
45
|
+
gamma = float(self.p.gamma)
|
|
46
|
+
if not self._initialized:
|
|
47
|
+
self._l0 = self._l1 = self._l2 = self._l3 = roc
|
|
48
|
+
self._initialized = True
|
|
49
|
+
l0_prev, l1_prev, l2_prev, l3_prev = self._l0, self._l1, self._l2, self._l3
|
|
50
|
+
l0 = (1.0 - gamma) * roc + gamma * l0_prev
|
|
51
|
+
l1 = -gamma * l0 + l0_prev + gamma * l1_prev
|
|
52
|
+
l2 = -gamma * l1 + l1_prev + gamma * l2_prev
|
|
53
|
+
l3 = -gamma * l2 + l2_prev + gamma * l3_prev
|
|
54
|
+
cu = 0.0
|
|
55
|
+
cd = 0.0
|
|
56
|
+
if l0 >= l1:
|
|
57
|
+
cu += l0 - l1
|
|
58
|
+
else:
|
|
59
|
+
cd += l1 - l0
|
|
60
|
+
if l1 >= l2:
|
|
61
|
+
cu += l1 - l2
|
|
62
|
+
else:
|
|
63
|
+
cd += l2 - l1
|
|
64
|
+
if l2 >= l3:
|
|
65
|
+
cu += l2 - l3
|
|
66
|
+
else:
|
|
67
|
+
cd += l3 - l2
|
|
68
|
+
lroc = cu / (cu + cd) if (cu + cd) != 0 else 0.5
|
|
69
|
+
color = 2
|
|
70
|
+
if lroc > float(self.p.up_level):
|
|
71
|
+
color = 4
|
|
72
|
+
elif lroc > 0.5:
|
|
73
|
+
color = 3
|
|
74
|
+
if lroc < float(self.p.dn_level):
|
|
75
|
+
color = 0
|
|
76
|
+
elif lroc < 0.5:
|
|
77
|
+
color = 1
|
|
78
|
+
self.lines.lroc[0] = lroc
|
|
79
|
+
self.lines.midline[0] = 0.5
|
|
80
|
+
self.lines.color[0] = color
|
|
81
|
+
self._l0, self._l1, self._l2, self._l3 = l0, l1, l2, l3
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Functional-test indicators migrated to contrib.
|
|
3
|
+
|
|
4
|
+
Generated from a single functional strategy module to preserve file-local
|
|
5
|
+
helper functions and constants without cross-test name collisions.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .. import Indicator
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"LeManSignalIndicator",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class LeManSignalIndicator(Indicator):
|
|
16
|
+
"""Reconstructs LeManSignal from its MQ5 source.
|
|
17
|
+
|
|
18
|
+
Compares two consecutive LPeriod-window high/low ranges shifted by 1 bar
|
|
19
|
+
and by LPeriod bars to detect breakouts.
|
|
20
|
+
buy_arrow: H3<=H4 && H1>H2 (high range expansion upward)
|
|
21
|
+
sell_arrow: L3>=L4 && L1<L2 (low range expansion downward)
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
lines = ("buy_arrow", "sell_arrow")
|
|
25
|
+
params = (
|
|
26
|
+
("lperiod", 12),
|
|
27
|
+
("point", 0.0001),
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
def __init__(self):
|
|
31
|
+
"""Store LPeriod/rules and initialize lookback requirements."""
|
|
32
|
+
self._lp = int(self.p.lperiod)
|
|
33
|
+
self.addminperiod(self._lp * 2 + 3)
|
|
34
|
+
|
|
35
|
+
def next(self):
|
|
36
|
+
"""Compute LeManSignal buy/sell arrows from rolling high-low ranges."""
|
|
37
|
+
lp = self._lp
|
|
38
|
+
# MQ5 as-series indexing: bar=0 is current, bar+1 is 1 ago, etc.
|
|
39
|
+
# H1 = max high over [bar+1, bar+1+LPeriod) => [-1 .. -(lp)]
|
|
40
|
+
# H2 = max high over [bar+1+LPeriod, bar+1+2*LPeriod) => [-(lp+1) .. -(2*lp)]
|
|
41
|
+
# H3 = max high over [bar+2, bar+2+LPeriod) => [-2 .. -(lp+1)]
|
|
42
|
+
# H4 = max high over [bar+2+LPeriod, bar+2+2*LPeriod) => [-(lp+2) .. -(2*lp+1)]
|
|
43
|
+
H1 = max(float(self.data.high[-i]) for i in range(1, lp + 1))
|
|
44
|
+
H2 = max(float(self.data.high[-i]) for i in range(lp + 1, 2 * lp + 1))
|
|
45
|
+
H3 = max(float(self.data.high[-i]) for i in range(2, lp + 2))
|
|
46
|
+
H4 = max(float(self.data.high[-i]) for i in range(lp + 2, 2 * lp + 2))
|
|
47
|
+
|
|
48
|
+
L1 = min(float(self.data.low[-i]) for i in range(1, lp + 1))
|
|
49
|
+
L2 = min(float(self.data.low[-i]) for i in range(lp + 1, 2 * lp + 1))
|
|
50
|
+
L3 = min(float(self.data.low[-i]) for i in range(2, lp + 2))
|
|
51
|
+
L4 = min(float(self.data.low[-i]) for i in range(lp + 2, 2 * lp + 2))
|
|
52
|
+
|
|
53
|
+
buy_val = 0.0
|
|
54
|
+
sell_val = 0.0
|
|
55
|
+
pt = float(self.p.point)
|
|
56
|
+
|
|
57
|
+
if H3 <= H4 and H1 > H2:
|
|
58
|
+
buy_val = float(self.data.high[-1]) + pt
|
|
59
|
+
if L3 >= L4 and L1 < L2:
|
|
60
|
+
sell_val = float(self.data.low[-1]) - pt
|
|
61
|
+
|
|
62
|
+
self.lines.buy_arrow[0] = buy_val
|
|
63
|
+
self.lines.sell_arrow[0] = sell_val
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Functional-test indicators migrated to contrib.
|
|
3
|
+
|
|
4
|
+
Generated from a single functional strategy module to preserve file-local
|
|
5
|
+
helper functions and constants without cross-test name collisions.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from collections import deque
|
|
9
|
+
|
|
10
|
+
import pandas as pd
|
|
11
|
+
|
|
12
|
+
from .. import (
|
|
13
|
+
EMA,
|
|
14
|
+
SMA,
|
|
15
|
+
Indicator,
|
|
16
|
+
SmoothedMovingAverage,
|
|
17
|
+
WeightedMovingAverage,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
"LinearRegSlopeV2Indicator",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def resolve_ma_class(name):
|
|
26
|
+
"""Resolve a human-readable moving-average mode name to a Backtrader class.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
name: Strategy parameter value such as ``sma``, ``ema``, or ``smma``.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
The matching Backtrader moving-average indicator class.
|
|
33
|
+
"""
|
|
34
|
+
mode = str(name).lower()
|
|
35
|
+
if mode in {"sma", "mode_sma"}:
|
|
36
|
+
return SMA
|
|
37
|
+
if mode in {"ema", "mode_ema"}:
|
|
38
|
+
return EMA
|
|
39
|
+
if mode in {"smma", "mode_smma"}:
|
|
40
|
+
return SmoothedMovingAverage
|
|
41
|
+
return WeightedMovingAverage
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def resolve_price_line(data, mode):
|
|
45
|
+
"""Resolve an abstract price mode name to a concrete price series line.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
data: A Backtrader data feed exposing OHLCV lines.
|
|
49
|
+
mode: Price selector such as ``price_close``, ``price_open``, etc.
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
A line-like object representing the selected price calculation.
|
|
53
|
+
"""
|
|
54
|
+
price_mode = str(mode).lower()
|
|
55
|
+
if price_mode in {"price_open", "open"}:
|
|
56
|
+
return data.open
|
|
57
|
+
if price_mode in {"price_high", "high"}:
|
|
58
|
+
return data.high
|
|
59
|
+
if price_mode in {"price_low", "low"}:
|
|
60
|
+
return data.low
|
|
61
|
+
if price_mode in {"price_median", "median"}:
|
|
62
|
+
return (data.high + data.low) / 2.0
|
|
63
|
+
if price_mode in {"price_typical", "typical"}:
|
|
64
|
+
return (data.high + data.low + data.close) / 3.0
|
|
65
|
+
if price_mode in {"price_weighted", "weighted"}:
|
|
66
|
+
return (data.high + data.low + data.close + data.close) / 4.0
|
|
67
|
+
if price_mode in {"price_simpl", "simpl"}:
|
|
68
|
+
return (data.open + data.close) / 2.0
|
|
69
|
+
if price_mode in {"price_quarter", "quarter"}:
|
|
70
|
+
return (data.high + data.low + data.open + data.close) / 4.0
|
|
71
|
+
if price_mode in {"price_trendfollow0", "trendfollow0"}:
|
|
72
|
+
return (data.high + data.low + data.close + data.close) / 4.0
|
|
73
|
+
if price_mode in {"price_trendfollow1", "trendfollow1"}:
|
|
74
|
+
return (data.high + data.low + data.open + data.close + data.close) / 5.0
|
|
75
|
+
return data.close
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class LinearRegSlopeV2Indicator(Indicator):
|
|
79
|
+
"""Indicator that computes a linear-regression slope proxy and trigger line."""
|
|
80
|
+
|
|
81
|
+
lines = (
|
|
82
|
+
"reg_slope",
|
|
83
|
+
"trigger",
|
|
84
|
+
)
|
|
85
|
+
params = (
|
|
86
|
+
("sl_method", "sma"),
|
|
87
|
+
("sl_length", 12),
|
|
88
|
+
("sl_phase", 15),
|
|
89
|
+
("ipc", "price_close"),
|
|
90
|
+
("trigger_shift", 1),
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
def __init__(self):
|
|
94
|
+
"""Initialize smoothing, regression buffers, and phase-shift settings."""
|
|
95
|
+
ma_cls = resolve_ma_class(self.p.sl_method)
|
|
96
|
+
price_line = resolve_price_line(self.data, self.p.ipc)
|
|
97
|
+
self.smooth = ma_cls(price_line, period=self.p.sl_length)
|
|
98
|
+
self._window = deque(maxlen=self.p.sl_length)
|
|
99
|
+
self._sum_x = self.p.sl_length * (self.p.sl_length - 1) * 0.5
|
|
100
|
+
sum_x_sqr = (
|
|
101
|
+
(self.p.sl_length - 1.0) * self.p.sl_length * (2.0 * self.p.sl_length - 1.0) / 6.0
|
|
102
|
+
)
|
|
103
|
+
self._divisor = self._sum_x * self._sum_x - self.p.sl_length * sum_x_sqr
|
|
104
|
+
if self.p.trigger_shift > self.p.sl_length - 2:
|
|
105
|
+
self._trig_shift = 1
|
|
106
|
+
self._trig_shift_back = self.p.sl_length - 2
|
|
107
|
+
else:
|
|
108
|
+
self._trig_shift = self.p.sl_length - 1 - self.p.trigger_shift
|
|
109
|
+
self._trig_shift_back = self.p.trigger_shift
|
|
110
|
+
self.addminperiod(self.p.sl_length + self.p.trigger_shift + 3)
|
|
111
|
+
|
|
112
|
+
def next(self):
|
|
113
|
+
"""Update one bar of regression slope and trigger calculations."""
|
|
114
|
+
self._window.appendleft(float(self.smooth[0]))
|
|
115
|
+
if len(self._window) < self.p.sl_length:
|
|
116
|
+
self.lines.reg_slope[0] = float("nan")
|
|
117
|
+
self.lines.trigger[0] = float("nan")
|
|
118
|
+
return
|
|
119
|
+
sum_y = sum(self._window[i] for i in range(self.p.sl_length))
|
|
120
|
+
sum_xy = sum(i * self._window[i] for i in range(self.p.sl_length))
|
|
121
|
+
slope = (
|
|
122
|
+
(self.p.sl_length * sum_xy - self._sum_x * sum_y) / self._divisor
|
|
123
|
+
if self._divisor
|
|
124
|
+
else float("nan")
|
|
125
|
+
)
|
|
126
|
+
intercept = (sum_y - slope * self._sum_x) / self.p.sl_length
|
|
127
|
+
reg_value = intercept + slope * self._trig_shift
|
|
128
|
+
self.lines.reg_slope[0] = reg_value
|
|
129
|
+
if len(self) > self._trig_shift_back and not pd.isna(
|
|
130
|
+
self.lines.reg_slope[-self._trig_shift_back]
|
|
131
|
+
):
|
|
132
|
+
self.lines.trigger[0] = 2.0 * reg_value - float(
|
|
133
|
+
self.lines.reg_slope[-self._trig_shift_back]
|
|
134
|
+
)
|
|
135
|
+
else:
|
|
136
|
+
self.lines.trigger[0] = float("nan")
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Functional-test indicators migrated to contrib.
|
|
3
|
+
|
|
4
|
+
Generated from a single functional strategy module to preserve file-local
|
|
5
|
+
helper functions and constants without cross-test name collisions.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .. import Indicator
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"LocoIndicator",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _applied_price(data, mode, ago=0):
|
|
16
|
+
mode = str(mode).lower()
|
|
17
|
+
o = float(data.open[ago])
|
|
18
|
+
h = float(data.high[ago])
|
|
19
|
+
low_price = float(data.low[ago])
|
|
20
|
+
c = float(data.close[ago])
|
|
21
|
+
if mode in ("price_open", "open", "price_open_"):
|
|
22
|
+
return o
|
|
23
|
+
if mode in ("price_high", "high", "price_high_"):
|
|
24
|
+
return h
|
|
25
|
+
if mode in ("price_low", "low", "price_low_"):
|
|
26
|
+
return low_price
|
|
27
|
+
if mode in ("price_median", "median", "price_median_"):
|
|
28
|
+
return (h + low_price) / 2.0
|
|
29
|
+
if mode in ("price_typical", "typical", "price_typical_"):
|
|
30
|
+
return (h + low_price + c) / 3.0
|
|
31
|
+
if mode in ("price_weighted", "weighted", "price_weighted_"):
|
|
32
|
+
return (h + low_price + 2.0 * c) / 4.0
|
|
33
|
+
if mode in ("price_simpl", "simpl", "simple", "price_simpl_"):
|
|
34
|
+
return (o + c) / 2.0
|
|
35
|
+
if mode in ("price_quarter", "quarter", "price_quarter_"):
|
|
36
|
+
return (h + low_price + o + c) / 4.0
|
|
37
|
+
return c
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class LocoIndicator(Indicator):
|
|
41
|
+
"""Loco follow-through line with a binary bullish/bearish color flag.
|
|
42
|
+
|
|
43
|
+
Tracks the applied price and produces a ``loco`` line plus a ``color`` flag
|
|
44
|
+
(0 = bullish, 1 = bearish) that flips when price reverses its run of higher
|
|
45
|
+
or lower readings.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
lines = ("loco", "color")
|
|
49
|
+
params = (
|
|
50
|
+
("length", 1),
|
|
51
|
+
("ipc", "price_close_"),
|
|
52
|
+
("price_shift_points", 0.0),
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
def __init__(self):
|
|
56
|
+
"""Reserve the warm-up window and initialise carry-forward state."""
|
|
57
|
+
self.addminperiod(max(int(self.p.length), 1) + 2)
|
|
58
|
+
self._initialized = False
|
|
59
|
+
self._prev = None
|
|
60
|
+
|
|
61
|
+
def next(self):
|
|
62
|
+
"""Update the Loco line and color flag for the current bar."""
|
|
63
|
+
series0 = _applied_price(self.data, self.p.ipc, 0)
|
|
64
|
+
if not self._initialized:
|
|
65
|
+
result = series0
|
|
66
|
+
color = 0
|
|
67
|
+
self._prev = result
|
|
68
|
+
self._initialized = True
|
|
69
|
+
else:
|
|
70
|
+
prev = float(self._prev)
|
|
71
|
+
ago = min(int(self.p.length), len(self.data) - 1)
|
|
72
|
+
series1 = _applied_price(self.data, self.p.ipc, -ago)
|
|
73
|
+
if series1 > prev and series0 > prev:
|
|
74
|
+
result = max(prev, series0 * 0.999)
|
|
75
|
+
color = 0
|
|
76
|
+
elif series1 < prev and series0 < prev:
|
|
77
|
+
result = min(prev, series0 * 1.001)
|
|
78
|
+
color = 1
|
|
79
|
+
else:
|
|
80
|
+
if series0 > prev:
|
|
81
|
+
result = series0 * 0.999
|
|
82
|
+
color = 0
|
|
83
|
+
else:
|
|
84
|
+
result = series0 * 1.001
|
|
85
|
+
color = 1
|
|
86
|
+
self._prev = result
|
|
87
|
+
self.lines.loco[0] = result + float(self.p.price_shift_points)
|
|
88
|
+
self.lines.color[0] = color
|
|
@@ -0,0 +1,185 @@
|
|
|
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
|
+
StandardDeviation,
|
|
14
|
+
WeightedMovingAverage,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
"LRMAIndicator",
|
|
19
|
+
"ChangeOfVolatilityIndicator",
|
|
20
|
+
"VininITrendLRMAIndicator",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def resolve_ma_class(name):
|
|
25
|
+
"""Map a moving-average method name to a backtrader indicator class.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
name: Moving-average method identifier (e.g. ``sma``, ``ema``,
|
|
29
|
+
``smma``).
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
The backtrader moving-average indicator class matching ``name``,
|
|
33
|
+
defaulting to WeightedMovingAverage for unknown names.
|
|
34
|
+
"""
|
|
35
|
+
mode = str(name).lower()
|
|
36
|
+
if mode in {"sma", "mode_sma"}:
|
|
37
|
+
return SimpleMovingAverage
|
|
38
|
+
if mode in {
|
|
39
|
+
"ema",
|
|
40
|
+
"mode_ema",
|
|
41
|
+
"ama",
|
|
42
|
+
"mode_ama",
|
|
43
|
+
"jjma",
|
|
44
|
+
"mode_jjma",
|
|
45
|
+
"jurx",
|
|
46
|
+
"mode_jurx",
|
|
47
|
+
"parma",
|
|
48
|
+
"mode_parma",
|
|
49
|
+
"t3",
|
|
50
|
+
"mode_t3",
|
|
51
|
+
"vidya",
|
|
52
|
+
"mode_vidya",
|
|
53
|
+
}:
|
|
54
|
+
return ExponentialMovingAverage
|
|
55
|
+
if mode in {"smma", "mode_smma"}:
|
|
56
|
+
return SmoothedMovingAverage
|
|
57
|
+
return WeightedMovingAverage
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def resolve_price_line(data, mode):
|
|
61
|
+
"""Select the price line for a given applied-price mode.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
data: The data feed exposing open/high/low/close lines.
|
|
65
|
+
mode: Applied-price identifier (e.g. ``price_close``, ``price_median``,
|
|
66
|
+
``price_typical``, ``price_weighted``).
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
The data line or derived line expression for the requested price mode,
|
|
70
|
+
defaulting to the close line.
|
|
71
|
+
"""
|
|
72
|
+
price_mode = str(mode).lower()
|
|
73
|
+
if price_mode in {"price_open", "open"}:
|
|
74
|
+
return data.open
|
|
75
|
+
if price_mode in {"price_high", "high"}:
|
|
76
|
+
return data.high
|
|
77
|
+
if price_mode in {"price_low", "low"}:
|
|
78
|
+
return data.low
|
|
79
|
+
if price_mode in {"price_median", "median"}:
|
|
80
|
+
return (data.high + data.low) / 2.0
|
|
81
|
+
if price_mode in {"price_typical", "typical"}:
|
|
82
|
+
return (data.high + data.low + data.close) / 3.0
|
|
83
|
+
if price_mode in {"price_weighted", "weighted"}:
|
|
84
|
+
return (data.high + data.low + data.close + data.close) / 4.0
|
|
85
|
+
return data.close
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class LRMAIndicator(Indicator):
|
|
89
|
+
"""Linear regression moving average projected to the latest bar."""
|
|
90
|
+
|
|
91
|
+
lines = ("lrma",)
|
|
92
|
+
params = (("period", 13),)
|
|
93
|
+
|
|
94
|
+
def __init__(self):
|
|
95
|
+
"""Set the minimum period required before the LRMA can be computed."""
|
|
96
|
+
self.addminperiod(int(self.p.period))
|
|
97
|
+
|
|
98
|
+
def next(self):
|
|
99
|
+
"""Fit a least-squares line over the window and emit its endpoint."""
|
|
100
|
+
period = int(self.p.period)
|
|
101
|
+
xs = list(range(period))
|
|
102
|
+
ys = [float(self.data[-period + 1 + i]) for i in range(period)]
|
|
103
|
+
mean_x = sum(xs) / period
|
|
104
|
+
mean_y = sum(ys) / period
|
|
105
|
+
num = sum((x - mean_x) * (y - mean_y) for x, y in zip(xs, ys))
|
|
106
|
+
den = sum((x - mean_x) ** 2 for x in xs)
|
|
107
|
+
slope = num / den if den else 0.0
|
|
108
|
+
intercept = mean_y - slope * mean_x
|
|
109
|
+
self.lines.lrma[0] = intercept + slope * (period - 1)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class ChangeOfVolatilityIndicator(Indicator):
|
|
113
|
+
"""Ratio of short- to long-window momentum dispersion (as a percentage)."""
|
|
114
|
+
|
|
115
|
+
lines = ("trend",)
|
|
116
|
+
params = (
|
|
117
|
+
("mperiod", 1),
|
|
118
|
+
("short", 6),
|
|
119
|
+
("long", 100),
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
def __init__(self):
|
|
123
|
+
"""Build short/long momentum SMAs and standard deviations."""
|
|
124
|
+
period = int(self.p.mperiod)
|
|
125
|
+
momentum = self.data.close - self.data.close(-period)
|
|
126
|
+
self._sma_long = SimpleMovingAverage(momentum, period=max(1, int(self.p.long)))
|
|
127
|
+
self._sma_short = SimpleMovingAverage(momentum, period=max(1, int(self.p.short)))
|
|
128
|
+
self._std_long = StandardDeviation(momentum, period=max(1, int(self.p.long)))
|
|
129
|
+
self._std_short = StandardDeviation(momentum, period=max(1, int(self.p.short)))
|
|
130
|
+
self.addminperiod(int(self.p.mperiod) + max(int(self.p.short), int(self.p.long)) + 3)
|
|
131
|
+
|
|
132
|
+
def next(self):
|
|
133
|
+
"""Emit the short/long volatility ratio scaled to a percentage."""
|
|
134
|
+
long_std = float(self._std_long[0])
|
|
135
|
+
short_std = float(self._std_short[0])
|
|
136
|
+
self.lines.trend[0] = 100.0 * short_std / long_std if long_std else 0.0
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class VininITrendLRMAIndicator(Indicator):
|
|
140
|
+
"""Trend oscillator scoring LRMA against a fan of moving averages."""
|
|
141
|
+
|
|
142
|
+
lines = ("trend",)
|
|
143
|
+
params = (
|
|
144
|
+
("lrma_period", 13),
|
|
145
|
+
("ma_method1", "sma"),
|
|
146
|
+
("length1", 3),
|
|
147
|
+
("phase1", 15),
|
|
148
|
+
("ma_step", 10),
|
|
149
|
+
("ma_count", 10),
|
|
150
|
+
("ma_method2", "jjma"),
|
|
151
|
+
("length2", 20),
|
|
152
|
+
("phase2", 100),
|
|
153
|
+
("ipc", "price_close"),
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
def __init__(self):
|
|
157
|
+
"""Construct the LRMA, the MA fan, and the output smoother."""
|
|
158
|
+
price_line = resolve_price_line(self.data, self.p.ipc)
|
|
159
|
+
self._lrma = LRMAIndicator(price_line, period=self.p.lrma_period)
|
|
160
|
+
periods = [
|
|
161
|
+
int(self.p.length1 + idx * self.p.ma_step) for idx in range(int(self.p.ma_count))
|
|
162
|
+
]
|
|
163
|
+
ma_cls = resolve_ma_class(self.p.ma_method1)
|
|
164
|
+
self._ma_lines = [ma_cls(self._lrma.lrma, period=max(1, p)) for p in periods]
|
|
165
|
+
smooth_cls = resolve_ma_class(self.p.ma_method2)
|
|
166
|
+
self._smooth = smooth_cls(self.lines.trend, period=max(1, int(self.p.length2)))
|
|
167
|
+
self.addminperiod(int(self.p.lrma_period) + max(periods) + int(self.p.length2) + 5)
|
|
168
|
+
|
|
169
|
+
def next(self):
|
|
170
|
+
"""Score LRMA versus the MA fan and exponentially smooth the result."""
|
|
171
|
+
lrma_value = float(self._lrma.lrma[0])
|
|
172
|
+
score = 0
|
|
173
|
+
for ma_line in self._ma_lines:
|
|
174
|
+
if lrma_value > float(ma_line[0]):
|
|
175
|
+
score += 1
|
|
176
|
+
else:
|
|
177
|
+
score -= 1
|
|
178
|
+
raw = 100.0 * score / max(1, len(self._ma_lines))
|
|
179
|
+
period = max(1, int(self.p.length2))
|
|
180
|
+
alpha = 2.0 / (period + 1.0)
|
|
181
|
+
prev = float(self.lines.trend[-1]) if len(self) > 0 else raw
|
|
182
|
+
if len(self) == 0:
|
|
183
|
+
self.lines.trend[0] = raw
|
|
184
|
+
else:
|
|
185
|
+
self.lines.trend[0] = alpha * raw + (1.0 - alpha) * prev
|