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,125 @@
|
|
|
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
|
+
BollingerBands,
|
|
10
|
+
ExponentialMovingAverage,
|
|
11
|
+
Indicator,
|
|
12
|
+
SimpleMovingAverage,
|
|
13
|
+
SmoothedMovingAverage,
|
|
14
|
+
WeightedMovingAverage,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
"ITrendIndicator",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def get_price_line(data, price_mode):
|
|
23
|
+
"""Return the price line of ``data`` matching the requested mode.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
data: A data feed exposing open/high/low/close lines.
|
|
27
|
+
price_mode: Price selector such as close, open, high, low, median,
|
|
28
|
+
typical, or weighted (with optional ``price_*`` prefixes).
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
The corresponding price line or derived price expression.
|
|
32
|
+
|
|
33
|
+
Raises:
|
|
34
|
+
ValueError: If ``price_mode`` is not recognised.
|
|
35
|
+
"""
|
|
36
|
+
mode = str(price_mode).lower()
|
|
37
|
+
if mode in ("close", "price_close", "price_close_"):
|
|
38
|
+
return data.close
|
|
39
|
+
if mode in ("open", "price_open", "price_open_"):
|
|
40
|
+
return data.open
|
|
41
|
+
if mode in ("high", "price_high", "price_high_"):
|
|
42
|
+
return data.high
|
|
43
|
+
if mode in ("low", "price_low", "price_low_"):
|
|
44
|
+
return data.low
|
|
45
|
+
if mode in ("median", "price_median", "price_median_"):
|
|
46
|
+
return (data.high + data.low) / 2.0
|
|
47
|
+
if mode in ("typical", "price_typical", "price_typical_"):
|
|
48
|
+
return (data.high + data.low + data.close) / 3.0
|
|
49
|
+
if mode in ("weighted", "price_weighted", "price_weighted_"):
|
|
50
|
+
return (data.high + data.low + data.close + data.close) / 4.0
|
|
51
|
+
raise ValueError(f"Unsupported price mode: {price_mode}")
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def build_ma(price_line, period, ma_type):
|
|
55
|
+
"""Construct a moving average indicator of the requested type.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
price_line: The input price line to smooth.
|
|
59
|
+
period: Lookback length for the moving average.
|
|
60
|
+
ma_type: Moving average type (SMA, EMA, SMMA/LWMA or their ``MODE_*``
|
|
61
|
+
aliases).
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
The instantiated moving average indicator.
|
|
65
|
+
|
|
66
|
+
Raises:
|
|
67
|
+
ValueError: If ``ma_type`` is not supported.
|
|
68
|
+
"""
|
|
69
|
+
mode = str(ma_type).upper()
|
|
70
|
+
mapping = {
|
|
71
|
+
"MODE_SMA": SimpleMovingAverage,
|
|
72
|
+
"SMA": SimpleMovingAverage,
|
|
73
|
+
"MODE_EMA": ExponentialMovingAverage,
|
|
74
|
+
"EMA": ExponentialMovingAverage,
|
|
75
|
+
"MODE_SMMA": SmoothedMovingAverage,
|
|
76
|
+
"SMMA": SmoothedMovingAverage,
|
|
77
|
+
"MODE_LWMA": WeightedMovingAverage,
|
|
78
|
+
"LWMA": WeightedMovingAverage,
|
|
79
|
+
}
|
|
80
|
+
if mode not in mapping:
|
|
81
|
+
raise ValueError(f"Unsupported ma_type: {ma_type}")
|
|
82
|
+
return mapping[mode](price_line, period=period)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class ITrendIndicator(Indicator):
|
|
86
|
+
"""i_Trend indicator producing primary and signal crossover lines.
|
|
87
|
+
|
|
88
|
+
The ``primary`` line is the selected price minus a Bollinger band line and
|
|
89
|
+
the ``signal`` line is a moving average mirrored around the bar's high/low
|
|
90
|
+
range; their crossovers drive the strategy's entries and exits.
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
lines = ("primary", "signal")
|
|
94
|
+
params = (
|
|
95
|
+
("price_type", "close"),
|
|
96
|
+
("ma_period", 13),
|
|
97
|
+
("ma_type", "EMA"),
|
|
98
|
+
("ma_price", "close"),
|
|
99
|
+
("bb_period", 20),
|
|
100
|
+
("deviation", 2.0),
|
|
101
|
+
("bb_price", "close"),
|
|
102
|
+
("bb_mode", 0),
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
def __init__(self):
|
|
106
|
+
"""Wire the moving average and Bollinger band into the output lines."""
|
|
107
|
+
price_type_line = get_price_line(self.data, self.p.price_type)
|
|
108
|
+
ma_price_line = get_price_line(self.data, self.p.ma_price)
|
|
109
|
+
bb_price_line = get_price_line(self.data, self.p.bb_price)
|
|
110
|
+
ma = build_ma(ma_price_line, int(self.p.ma_period), self.p.ma_type)
|
|
111
|
+
bands = BollingerBands(
|
|
112
|
+
bb_price_line, period=int(self.p.bb_period), devfactor=float(self.p.deviation)
|
|
113
|
+
)
|
|
114
|
+
mode = int(self.p.bb_mode)
|
|
115
|
+
if mode == 0:
|
|
116
|
+
band_line = bands.mid
|
|
117
|
+
elif mode == 1:
|
|
118
|
+
band_line = bands.top
|
|
119
|
+
elif mode == 2:
|
|
120
|
+
band_line = bands.bot
|
|
121
|
+
else:
|
|
122
|
+
raise ValueError(f"Unsupported bb_mode: {self.p.bb_mode}")
|
|
123
|
+
self.l.primary = price_type_line - band_line
|
|
124
|
+
self.l.signal = (ma * 2.0) - self.data.low - self.data.high
|
|
125
|
+
self.addminperiod(max(int(self.p.ma_period), int(self.p.bb_period)) + 5)
|
|
@@ -0,0 +1,39 @@
|
|
|
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
|
+
"IAMMAIndicator",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class IAMMAIndicator(Indicator):
|
|
16
|
+
"""Indicator implementation of i-AMMA value progression."""
|
|
17
|
+
|
|
18
|
+
lines = ("value",)
|
|
19
|
+
params = (
|
|
20
|
+
("ma_period", 25),
|
|
21
|
+
("price_shift", 0),
|
|
22
|
+
("point", 0.01),
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
def __init__(self):
|
|
26
|
+
"""Initialize i-AMMA offset and minimum startup bars."""
|
|
27
|
+
self.price_offset = float(self.p.point) * float(self.p.price_shift)
|
|
28
|
+
self.addminperiod(2)
|
|
29
|
+
|
|
30
|
+
def next(self):
|
|
31
|
+
"""Compute adaptive MA value for current bar."""
|
|
32
|
+
if len(self) == 1:
|
|
33
|
+
self.l.value[0] = float(self.data.close[0])
|
|
34
|
+
return
|
|
35
|
+
period = max(int(self.p.ma_period), 1)
|
|
36
|
+
prev = float(self.l.value[-1])
|
|
37
|
+
price = float(self.data.close[0])
|
|
38
|
+
amma = (((period - 1) * (prev - self.price_offset)) + price) / period
|
|
39
|
+
self.l.value[0] = amma + self.price_offset
|
|
@@ -0,0 +1,33 @@
|
|
|
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
|
+
Indicator,
|
|
10
|
+
SimpleMovingAverage,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"IndexedMovingAverage",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class IndexedMovingAverage(Indicator):
|
|
19
|
+
"""Indicator that normalizes price-to-MA imbalance for directional signals."""
|
|
20
|
+
|
|
21
|
+
lines = ("ima",)
|
|
22
|
+
params = (("period", 5),)
|
|
23
|
+
|
|
24
|
+
def __init__(self):
|
|
25
|
+
"""Initialize MA line and warmup period for indicator output."""
|
|
26
|
+
self.ma = SimpleMovingAverage(self.data.close, period=self.p.period)
|
|
27
|
+
self.addminperiod(self.p.period + 1)
|
|
28
|
+
|
|
29
|
+
def next(self):
|
|
30
|
+
"""Write indexed moving-average deviation to ``lines.ima`` for current bar."""
|
|
31
|
+
ma = float(self.ma[0])
|
|
32
|
+
close = float(self.data.close[0])
|
|
33
|
+
self.lines.ima[0] = 0.0 if abs(ma) < 1e-12 else (close / ma) - 1.0
|
|
@@ -0,0 +1,51 @@
|
|
|
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
|
+
"InstantaneousTrendFilterIndicator",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class InstantaneousTrendFilterIndicator(Indicator):
|
|
16
|
+
"""Indicator computing trend and trigger values from a low-lag trend filter."""
|
|
17
|
+
|
|
18
|
+
lines = ("trend", "trigger")
|
|
19
|
+
params = (("alpha", 0.07),)
|
|
20
|
+
|
|
21
|
+
def __init__(self):
|
|
22
|
+
"""Initialize coefficients and warm-up requirements."""
|
|
23
|
+
alpha = float(self.p.alpha)
|
|
24
|
+
a2 = alpha * alpha
|
|
25
|
+
self.k0 = alpha - a2 / 4.0
|
|
26
|
+
self.k1 = 0.5 * a2
|
|
27
|
+
self.k2 = alpha - 0.75 * a2
|
|
28
|
+
self.k3 = 2.0 * (1.0 - alpha)
|
|
29
|
+
self.k4 = (1.0 - alpha) ** 2
|
|
30
|
+
self.addminperiod(1)
|
|
31
|
+
|
|
32
|
+
def next(self):
|
|
33
|
+
"""Compute the current trend/trigger outputs."""
|
|
34
|
+
price0 = float(self.data.close[0])
|
|
35
|
+
if len(self) <= 4:
|
|
36
|
+
trend = price0
|
|
37
|
+
else:
|
|
38
|
+
price1 = float(self.data.close[-1])
|
|
39
|
+
price2 = float(self.data.close[-2])
|
|
40
|
+
trend = (
|
|
41
|
+
self.k0 * price0
|
|
42
|
+
+ self.k1 * price1
|
|
43
|
+
- self.k2 * price2
|
|
44
|
+
+ self.k3 * float(self.l.trend[-1])
|
|
45
|
+
- self.k4 * float(self.l.trend[-2])
|
|
46
|
+
)
|
|
47
|
+
self.l.trend[0] = trend
|
|
48
|
+
if len(self) <= 2:
|
|
49
|
+
self.l.trigger[0] = trend
|
|
50
|
+
else:
|
|
51
|
+
self.l.trigger[0] = 2.0 * trend - float(self.l.trend[-2])
|
|
@@ -0,0 +1,41 @@
|
|
|
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
|
+
"InverseReactionIndicator",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class InverseReactionIndicator(Indicator):
|
|
16
|
+
"""Indicator that tracks candle reaction amplitude and dynamic thresholds."""
|
|
17
|
+
|
|
18
|
+
lines = ("price_change", "upper_level", "lower_level")
|
|
19
|
+
params = (
|
|
20
|
+
("ma_period", 3),
|
|
21
|
+
("coefficient", 1.618),
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
def __init__(self):
|
|
25
|
+
"""Set minimum required history for moving-average reaction computation."""
|
|
26
|
+
self.addminperiod(self.p.ma_period)
|
|
27
|
+
|
|
28
|
+
def next(self):
|
|
29
|
+
"""Compute per-bar price-change and dynamic reaction upper/lower levels."""
|
|
30
|
+
price_change = float(self.data.close[0] - self.data.open[0])
|
|
31
|
+
self.lines.price_change[0] = price_change
|
|
32
|
+
if len(self) < self.p.ma_period:
|
|
33
|
+
self.lines.upper_level[0] = float("nan")
|
|
34
|
+
self.lines.lower_level[0] = float("nan")
|
|
35
|
+
return
|
|
36
|
+
total = 0.0
|
|
37
|
+
for i in range(self.p.ma_period):
|
|
38
|
+
total += abs(float(self.data.close[-i] - self.data.open[-i]))
|
|
39
|
+
dcl = (total / float(self.p.ma_period)) * float(self.p.coefficient)
|
|
40
|
+
self.lines.upper_level[0] = dcl
|
|
41
|
+
self.lines.lower_level[0] = -dcl
|
|
@@ -0,0 +1,95 @@
|
|
|
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
|
+
ATR,
|
|
10
|
+
Indicator,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"IRSISignIndicator",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _applied_price(data, price_type, ago=0):
|
|
19
|
+
"""Resolve applied price by type and history shift."""
|
|
20
|
+
o = float(data.open[-ago])
|
|
21
|
+
h = float(data.high[-ago])
|
|
22
|
+
low_price = float(data.low[-ago])
|
|
23
|
+
c = float(data.close[-ago])
|
|
24
|
+
if price_type == 0:
|
|
25
|
+
return c
|
|
26
|
+
if price_type == 1:
|
|
27
|
+
return o
|
|
28
|
+
if price_type == 2:
|
|
29
|
+
return h
|
|
30
|
+
if price_type == 3:
|
|
31
|
+
return low_price
|
|
32
|
+
if price_type == 4:
|
|
33
|
+
return (h + low_price) / 2.0
|
|
34
|
+
if price_type == 5:
|
|
35
|
+
return (h + low_price + c) / 3.0
|
|
36
|
+
if price_type == 6:
|
|
37
|
+
return (h + low_price + c + c) / 4.0
|
|
38
|
+
return c
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class IRSISignIndicator(Indicator):
|
|
42
|
+
"""Compute RSI sign-flip levels and adaptive ATR-adjusted marker lines."""
|
|
43
|
+
|
|
44
|
+
lines = ("sell", "buy", "rsi", "atr")
|
|
45
|
+
params = (
|
|
46
|
+
("atr_period", 14),
|
|
47
|
+
("rsi_period", 14),
|
|
48
|
+
("rsi_price", 0),
|
|
49
|
+
("up_level", 70),
|
|
50
|
+
("dn_level", 30),
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
def __init__(self):
|
|
54
|
+
"""Initialize ATR series and minimum required history."""
|
|
55
|
+
self._atr = ATR(self.data, period=int(self.p.atr_period))
|
|
56
|
+
self.addminperiod(max(int(self.p.atr_period), int(self.p.rsi_period)) + 2)
|
|
57
|
+
|
|
58
|
+
def _calc_rsi(self):
|
|
59
|
+
"""Calculate RSI manually from configured applied prices."""
|
|
60
|
+
period = int(self.p.rsi_period)
|
|
61
|
+
gains = []
|
|
62
|
+
losses = []
|
|
63
|
+
for i in range(period):
|
|
64
|
+
p0 = _applied_price(self.data, int(self.p.rsi_price), i)
|
|
65
|
+
p1 = _applied_price(self.data, int(self.p.rsi_price), i + 1)
|
|
66
|
+
delta = p0 - p1
|
|
67
|
+
gains.append(max(delta, 0.0))
|
|
68
|
+
losses.append(max(-delta, 0.0))
|
|
69
|
+
avg_gain = sum(gains) / period if period else 0.0
|
|
70
|
+
avg_loss = sum(losses) / period if period else 0.0
|
|
71
|
+
if avg_loss == 0.0:
|
|
72
|
+
return 100.0 if avg_gain > 0.0 else 50.0
|
|
73
|
+
rs = avg_gain / avg_loss
|
|
74
|
+
return 100.0 - (100.0 / (1.0 + rs))
|
|
75
|
+
|
|
76
|
+
def next(self):
|
|
77
|
+
"""Update buy/sell marker levels and RSI / ATR output lines."""
|
|
78
|
+
self.lines.sell[0] = float("nan")
|
|
79
|
+
self.lines.buy[0] = float("nan")
|
|
80
|
+
rsi_now = self._calc_rsi()
|
|
81
|
+
self.lines.rsi[0] = rsi_now
|
|
82
|
+
self.lines.atr[0] = float(self._atr[0])
|
|
83
|
+
|
|
84
|
+
if len(self) < 2:
|
|
85
|
+
return
|
|
86
|
+
|
|
87
|
+
rsi_prev = float(self.lines.rsi[-1])
|
|
88
|
+
atr_now = float(self._atr[0])
|
|
89
|
+
low_now = float(self.data.low[0])
|
|
90
|
+
high_now = float(self.data.high[0])
|
|
91
|
+
|
|
92
|
+
if rsi_now > float(self.p.dn_level) and rsi_prev <= float(self.p.dn_level):
|
|
93
|
+
self.lines.buy[0] = low_now - atr_now * 3.0 / 8.0
|
|
94
|
+
if rsi_now < float(self.p.up_level) and rsi_prev >= float(self.p.up_level):
|
|
95
|
+
self.lines.sell[0] = high_now + atr_now * 3.0 / 8.0
|
|
@@ -0,0 +1,59 @@
|
|
|
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
|
+
ATR,
|
|
10
|
+
Indicator,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"IWPRSignIndicator",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class IWPRSignIndicator(Indicator):
|
|
19
|
+
"""Indicator computing WPR buy/sell levels with ATR context."""
|
|
20
|
+
|
|
21
|
+
lines = ("sell", "buy", "wpr", "atr")
|
|
22
|
+
params = (
|
|
23
|
+
("atr_period", 14),
|
|
24
|
+
("wpr_period", 14),
|
|
25
|
+
("up_level", -30),
|
|
26
|
+
("dn_level", -70),
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
def __init__(self):
|
|
30
|
+
"""Initialize ATR source and required lookback."""
|
|
31
|
+
self._atr = ATR(self.data, period=int(self.p.atr_period))
|
|
32
|
+
self.addminperiod(max(int(self.p.atr_period), int(self.p.wpr_period)) + 2)
|
|
33
|
+
|
|
34
|
+
def _calc_wpr(self):
|
|
35
|
+
period = int(self.p.wpr_period)
|
|
36
|
+
highs = [float(self.data.high[-i]) for i in range(period)]
|
|
37
|
+
lows = [float(self.data.low[-i]) for i in range(period)]
|
|
38
|
+
hh = max(highs)
|
|
39
|
+
ll = min(lows)
|
|
40
|
+
cp = float(self.data.close[0])
|
|
41
|
+
if hh == ll:
|
|
42
|
+
return -50.0
|
|
43
|
+
return -100.0 * (hh - cp) / (hh - ll)
|
|
44
|
+
|
|
45
|
+
def next(self):
|
|
46
|
+
"""Compute WPR and create buy/sell trigger levels."""
|
|
47
|
+
self.lines.sell[0] = float("nan")
|
|
48
|
+
self.lines.buy[0] = float("nan")
|
|
49
|
+
wpr_now = self._calc_wpr()
|
|
50
|
+
self.lines.wpr[0] = wpr_now
|
|
51
|
+
self.lines.atr[0] = float(self._atr[0])
|
|
52
|
+
if len(self) < 2:
|
|
53
|
+
return
|
|
54
|
+
wpr_prev = float(self.lines.wpr[-1])
|
|
55
|
+
atr_now = float(self._atr[0])
|
|
56
|
+
if wpr_now > float(self.p.dn_level) and wpr_prev <= float(self.p.dn_level):
|
|
57
|
+
self.lines.buy[0] = float(self.data.low[0]) - atr_now * 3.0 / 8.0
|
|
58
|
+
if wpr_now < float(self.p.up_level) and wpr_prev >= float(self.p.up_level):
|
|
59
|
+
self.lines.sell[0] = float(self.data.high[0]) + atr_now * 3.0 / 8.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 collections import deque
|
|
9
|
+
|
|
10
|
+
from .. import (
|
|
11
|
+
ATR,
|
|
12
|
+
EMA,
|
|
13
|
+
RSI,
|
|
14
|
+
SMA,
|
|
15
|
+
Highest,
|
|
16
|
+
Indicator,
|
|
17
|
+
Lowest,
|
|
18
|
+
SmoothedMovingAverage,
|
|
19
|
+
WeightedMovingAverage,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
"JBrainTrend1SigIndicator",
|
|
24
|
+
"UltraRSIIndicator",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def resolve_ma_class(name):
|
|
29
|
+
"""Resolve a moving-average style name to a Backtrader indicator class.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
name: Requested moving-average mode, e.g., ``sma`` or ``ema``.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
Corresponding Backtrader moving-average indicator class.
|
|
36
|
+
"""
|
|
37
|
+
mode = str(name).lower()
|
|
38
|
+
if mode in {"sma", "mode_sma"}:
|
|
39
|
+
return SMA
|
|
40
|
+
if mode in {"smma", "mode_smma"}:
|
|
41
|
+
return SmoothedMovingAverage
|
|
42
|
+
if mode in {"lwma", "mode_lwma"}:
|
|
43
|
+
return WeightedMovingAverage
|
|
44
|
+
return EMA
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class CountSmoother:
|
|
48
|
+
"""Track a rolling series of values and return a smoothed aggregate.
|
|
49
|
+
|
|
50
|
+
Supports EMA-like, SMA, LWMA, and SMMA update rules used by the RSI module.
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
def __init__(self, method, period):
|
|
54
|
+
"""Initialize the smoother.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
method: Smoothing method name.
|
|
58
|
+
period: Window size used by SMA/LWMA/SMMA/EMA-style calculations.
|
|
59
|
+
"""
|
|
60
|
+
self.method = str(method).lower()
|
|
61
|
+
self.period = max(1, int(period))
|
|
62
|
+
self.state = None
|
|
63
|
+
self.values = deque(maxlen=self.period)
|
|
64
|
+
|
|
65
|
+
def update(self, value):
|
|
66
|
+
"""Update the smoother with a new sample and return the current value.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
value: New numeric sample.
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
Smoothed value after applying the configured method.
|
|
73
|
+
"""
|
|
74
|
+
value = float(value)
|
|
75
|
+
if self.method in {"sma", "mode_sma"}:
|
|
76
|
+
self.values.append(value)
|
|
77
|
+
return sum(self.values) / len(self.values)
|
|
78
|
+
if self.method in {"lwma", "mode_lwma"}:
|
|
79
|
+
self.values.append(value)
|
|
80
|
+
weights = list(range(1, len(self.values) + 1))
|
|
81
|
+
return sum(v * w for v, w in zip(self.values, weights)) / sum(weights)
|
|
82
|
+
if self.method in {"smma", "mode_smma"}:
|
|
83
|
+
if self.state is None:
|
|
84
|
+
self.state = value
|
|
85
|
+
else:
|
|
86
|
+
self.state = ((self.period - 1) * self.state + value) / self.period
|
|
87
|
+
return self.state
|
|
88
|
+
alpha = 2.0 / (self.period + 1.0)
|
|
89
|
+
if self.state is None:
|
|
90
|
+
self.state = value
|
|
91
|
+
else:
|
|
92
|
+
self.state = self.state + alpha * (value - self.state)
|
|
93
|
+
return self.state
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class JBrainTrend1SigIndicator(Indicator):
|
|
97
|
+
"""Generate directional trend-signal levels from ATR, stochastic, and MAs.
|
|
98
|
+
|
|
99
|
+
The indicator emits ``buy_signal`` and ``sell_signal`` pulses used by the
|
|
100
|
+
main strategy.
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
lines = (
|
|
104
|
+
"sell_signal",
|
|
105
|
+
"buy_signal",
|
|
106
|
+
)
|
|
107
|
+
params = (
|
|
108
|
+
("atr_period", 7),
|
|
109
|
+
("sto_period", 9),
|
|
110
|
+
("ma_method", "sma"),
|
|
111
|
+
("xlength", 7),
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
def __init__(self):
|
|
115
|
+
"""Build ATR, highest/lowest price extremes, and smoothing primitives."""
|
|
116
|
+
ma_cls = resolve_ma_class(self.p.ma_method)
|
|
117
|
+
self.atr = ATR(self.data, period=self.p.atr_period)
|
|
118
|
+
self.highest = Highest(self.data.high, period=self.p.sto_period)
|
|
119
|
+
self.lowest = Lowest(self.data.low, period=self.p.sto_period)
|
|
120
|
+
self.jh = ma_cls(self.data.high, period=self.p.xlength)
|
|
121
|
+
self.jl = ma_cls(self.data.low, period=self.p.xlength)
|
|
122
|
+
self.jc = ma_cls(self.data.close, period=self.p.xlength)
|
|
123
|
+
self._d = 2.3
|
|
124
|
+
self._s = 1.5
|
|
125
|
+
self._x1 = 53.0
|
|
126
|
+
self._x2 = 47.0
|
|
127
|
+
self._p_state = 0
|
|
128
|
+
self._old_trend = 0
|
|
129
|
+
self.addminperiod(max(self.p.atr_period, self.p.sto_period, self.p.xlength) + 3)
|
|
130
|
+
|
|
131
|
+
def next(self):
|
|
132
|
+
"""Evaluate one bar and update ``buy_signal``/``sell_signal`` outputs."""
|
|
133
|
+
self.lines.sell_signal[0] = 0.0
|
|
134
|
+
self.lines.buy_signal[0] = 0.0
|
|
135
|
+
highest = float(self.highest[0])
|
|
136
|
+
lowest = float(self.lowest[0])
|
|
137
|
+
close = float(self.data.close[0])
|
|
138
|
+
denom = highest - lowest
|
|
139
|
+
stochastic = 50.0 if denom == 0 else 100.0 * (close - lowest) / denom
|
|
140
|
+
atr_value = float(self.atr[0])
|
|
141
|
+
range_value = atr_value / self._d
|
|
142
|
+
range_shift = atr_value * self._s / 4.0
|
|
143
|
+
val3 = abs(float(self.jc[0]) - float(self.jc[-2]))
|
|
144
|
+
|
|
145
|
+
if stochastic < self._x2 and val3 > range_value:
|
|
146
|
+
self._p_state = 1
|
|
147
|
+
if stochastic > self._x1 and val3 > range_value:
|
|
148
|
+
self._p_state = 2
|
|
149
|
+
if val3 <= range_value:
|
|
150
|
+
return
|
|
151
|
+
|
|
152
|
+
if stochastic < self._x2 and self._p_state in (0, 1):
|
|
153
|
+
if self._old_trend > 0:
|
|
154
|
+
self.lines.sell_signal[0] = float(self.jh[0]) + range_shift
|
|
155
|
+
if len(self.data) > 1:
|
|
156
|
+
self._old_trend = -1
|
|
157
|
+
if stochastic > self._x1 and self._p_state in (0, 2):
|
|
158
|
+
if self._old_trend < 0:
|
|
159
|
+
self.lines.buy_signal[0] = float(self.jl[0]) - range_shift
|
|
160
|
+
if len(self.data) > 1:
|
|
161
|
+
self._old_trend = 1
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
class UltraRSIIndicator(Indicator):
|
|
165
|
+
"""Smooth RSI slope-count indicator with configurable averaging stages.
|
|
166
|
+
|
|
167
|
+
Counts bullish versus bearish RSI directional changes across multiple moving
|
|
168
|
+
average steps and smooths both counters for a stable signal.
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
lines = (
|
|
172
|
+
"bulls",
|
|
173
|
+
"bears",
|
|
174
|
+
)
|
|
175
|
+
params = (
|
|
176
|
+
("rsi_period", 13),
|
|
177
|
+
("applied_price", "close"),
|
|
178
|
+
("w_method", "jjma"),
|
|
179
|
+
("start_length", 3),
|
|
180
|
+
("nstep", 5),
|
|
181
|
+
("nsteps_total", 10),
|
|
182
|
+
("smooth_method", "jjma"),
|
|
183
|
+
("smooth_length", 3),
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
def __init__(self):
|
|
187
|
+
"""Initialize RSI series and helper smoothing state."""
|
|
188
|
+
price_line = self._price_line()
|
|
189
|
+
ma_cls = resolve_ma_class(self.p.w_method)
|
|
190
|
+
self.rsi = RSI(price_line, period=self.p.rsi_period, safediv=True)
|
|
191
|
+
self._series = [
|
|
192
|
+
ma_cls(self.rsi, period=max(1, int(self.p.start_length + step * self.p.nstep)))
|
|
193
|
+
for step in range(int(self.p.nsteps_total) + 1)
|
|
194
|
+
]
|
|
195
|
+
self._bull_smoother = CountSmoother(self.p.smooth_method, self.p.smooth_length)
|
|
196
|
+
self._bear_smoother = CountSmoother(self.p.smooth_method, self.p.smooth_length)
|
|
197
|
+
self.addminperiod(
|
|
198
|
+
self.p.rsi_period
|
|
199
|
+
+ self.p.start_length
|
|
200
|
+
+ self.p.nstep * self.p.nsteps_total
|
|
201
|
+
+ self.p.smooth_length
|
|
202
|
+
+ 5
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
def _price_line(self):
|
|
206
|
+
mode = str(self.p.applied_price).lower()
|
|
207
|
+
if mode == "open":
|
|
208
|
+
return self.data.open
|
|
209
|
+
if mode == "high":
|
|
210
|
+
return self.data.high
|
|
211
|
+
if mode == "low":
|
|
212
|
+
return self.data.low
|
|
213
|
+
if mode == "median":
|
|
214
|
+
return (self.data.high + self.data.low) / 2.0
|
|
215
|
+
if mode == "typical":
|
|
216
|
+
return (self.data.high + self.data.low + self.data.close) / 3.0
|
|
217
|
+
if mode == "weighted":
|
|
218
|
+
return (self.data.high + self.data.low + self.data.close + self.data.close) / 4.0
|
|
219
|
+
return self.data.close
|
|
220
|
+
|
|
221
|
+
def next(self):
|
|
222
|
+
"""Update bullish and bearish counters and write smoothed values."""
|
|
223
|
+
up_count = 0
|
|
224
|
+
down_count = 0
|
|
225
|
+
for series in self._series:
|
|
226
|
+
current = float(series[0])
|
|
227
|
+
previous = float(series[-1])
|
|
228
|
+
if current > previous:
|
|
229
|
+
up_count += 1
|
|
230
|
+
elif current < previous:
|
|
231
|
+
down_count += 1
|
|
232
|
+
self.lines.bulls[0] = self._bull_smoother.update(up_count)
|
|
233
|
+
self.lines.bears[0] = self._bear_smoother.update(down_count)
|