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,440 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""RSI Indicator Module - Relative Strength Index.
|
|
3
|
+
|
|
4
|
+
This module provides the RSI (Relative Strength Index) indicator
|
|
5
|
+
developed by J. Welles Wilder, Jr.
|
|
6
|
+
|
|
7
|
+
Classes:
|
|
8
|
+
RSI: RSI indicator.
|
|
9
|
+
UpDay/DownDay: Helper classes for RSI calculation.
|
|
10
|
+
|
|
11
|
+
Example:
|
|
12
|
+
class MyStrategy(bt.Strategy):
|
|
13
|
+
def __init__(self):
|
|
14
|
+
self.rsi = bt.indicators.RSI(self.data.close, period=14)
|
|
15
|
+
|
|
16
|
+
def next(self):
|
|
17
|
+
# RSI above 70 indicates overbought
|
|
18
|
+
if self.rsi.rsi[0] > 70:
|
|
19
|
+
self.sell()
|
|
20
|
+
# RSI below 30 indicates oversold
|
|
21
|
+
elif self.rsi.rsi[0] < 30:
|
|
22
|
+
self.buy()
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
import math
|
|
26
|
+
|
|
27
|
+
from . import Indicator, MovAv
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# Calculate RSI indicator
|
|
31
|
+
class UpDay(Indicator):
|
|
32
|
+
"""
|
|
33
|
+
Defined by J. Welles Wilder, Jr. in 1978 in his book *"New Concepts in
|
|
34
|
+
Technical Trading Systems"* for the RSI
|
|
35
|
+
|
|
36
|
+
Records days which have been "up", i.e.: the close price has been
|
|
37
|
+
higher than the day before.
|
|
38
|
+
|
|
39
|
+
Formula:
|
|
40
|
+
- upday = max (close - close_prev, 0)
|
|
41
|
+
|
|
42
|
+
See:
|
|
43
|
+
- http://en.wikipedia.org/wiki/Relative_strength_index
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
lines = ("upday",)
|
|
47
|
+
params = (("period", 1),)
|
|
48
|
+
|
|
49
|
+
def __init__(self):
|
|
50
|
+
"""Initialize the UpDay indicator.
|
|
51
|
+
|
|
52
|
+
Sets minimum period for up day calculation.
|
|
53
|
+
"""
|
|
54
|
+
super().__init__()
|
|
55
|
+
self.addminperiod(self.p.period + 1)
|
|
56
|
+
|
|
57
|
+
def next(self):
|
|
58
|
+
"""Calculate up day value for the current bar.
|
|
59
|
+
|
|
60
|
+
Returns max(close - close_period_ago, 0).
|
|
61
|
+
"""
|
|
62
|
+
diff = self.data[0] - self.data[-self.p.period]
|
|
63
|
+
self.lines.upday[0] = max(diff, 0.0)
|
|
64
|
+
|
|
65
|
+
def once(self, start, end):
|
|
66
|
+
"""Calculate up day values in runonce mode.
|
|
67
|
+
|
|
68
|
+
Returns max(price_change, 0) for each bar.
|
|
69
|
+
"""
|
|
70
|
+
darray = self.data.array
|
|
71
|
+
larray = self.lines.upday.array
|
|
72
|
+
period = self.p.period
|
|
73
|
+
|
|
74
|
+
while len(larray) < end:
|
|
75
|
+
larray.append(0.0)
|
|
76
|
+
|
|
77
|
+
for i in range(min(period, end, len(larray))):
|
|
78
|
+
larray[i] = 0.0
|
|
79
|
+
|
|
80
|
+
for i in range(period, min(end, len(darray))):
|
|
81
|
+
diff = darray[i] - darray[i - period]
|
|
82
|
+
larray[i] = max(diff, 0.0)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class DownDay(Indicator):
|
|
86
|
+
"""
|
|
87
|
+
Defined by J. Welles Wilder, Jr. in 1978 in his book *"New Concepts in
|
|
88
|
+
Technical Trading Systems"* for the RSI
|
|
89
|
+
|
|
90
|
+
Records days which have been "down", i.e.: the close price has been
|
|
91
|
+
lower than the day before.
|
|
92
|
+
|
|
93
|
+
Formula:
|
|
94
|
+
- downday = max(close_prev - close, 0)
|
|
95
|
+
|
|
96
|
+
See:
|
|
97
|
+
- http://en.wikipedia.org/wiki/Relative_strength_index
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
lines = ("downday",)
|
|
101
|
+
params = (("period", 1),)
|
|
102
|
+
|
|
103
|
+
def __init__(self):
|
|
104
|
+
"""Initialize the DownDay indicator.
|
|
105
|
+
|
|
106
|
+
Sets minimum period for down day calculation.
|
|
107
|
+
"""
|
|
108
|
+
super().__init__()
|
|
109
|
+
self.addminperiod(self.p.period + 1)
|
|
110
|
+
|
|
111
|
+
def next(self):
|
|
112
|
+
"""Calculate down day value for the current bar.
|
|
113
|
+
|
|
114
|
+
Returns max(close_period_ago - close, 0).
|
|
115
|
+
"""
|
|
116
|
+
diff = self.data[-self.p.period] - self.data[0]
|
|
117
|
+
self.lines.downday[0] = max(diff, 0.0)
|
|
118
|
+
|
|
119
|
+
def once(self, start, end):
|
|
120
|
+
"""Calculate down day values in runonce mode.
|
|
121
|
+
|
|
122
|
+
Returns max(-price_change, 0) for each bar.
|
|
123
|
+
"""
|
|
124
|
+
darray = self.data.array
|
|
125
|
+
larray = self.lines.downday.array
|
|
126
|
+
period = self.p.period
|
|
127
|
+
|
|
128
|
+
while len(larray) < end:
|
|
129
|
+
larray.append(0.0)
|
|
130
|
+
|
|
131
|
+
for i in range(min(period, end, len(larray))):
|
|
132
|
+
larray[i] = 0.0
|
|
133
|
+
|
|
134
|
+
for i in range(period, min(end, len(darray))):
|
|
135
|
+
diff = darray[i - period] - darray[i]
|
|
136
|
+
larray[i] = max(diff, 0.0)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class UpDayBool(Indicator):
|
|
140
|
+
"""
|
|
141
|
+
Defined by J. Welles Wilder, Jr. in 1978 in his book *"New Concepts in
|
|
142
|
+
Technical Trading Systems"* for the RSI
|
|
143
|
+
|
|
144
|
+
Records days which have been "up", i.e.: the close price has been
|
|
145
|
+
higher than the day before.
|
|
146
|
+
|
|
147
|
+
Note:
|
|
148
|
+
- This version returns a bool rather than the difference
|
|
149
|
+
|
|
150
|
+
Formula:
|
|
151
|
+
- upday = close > close_prev
|
|
152
|
+
|
|
153
|
+
See:
|
|
154
|
+
- http://en.wikipedia.org/wiki/Relative_strength_index
|
|
155
|
+
"""
|
|
156
|
+
|
|
157
|
+
lines = ("upday",)
|
|
158
|
+
params = (("period", 1),)
|
|
159
|
+
|
|
160
|
+
def __init__(self):
|
|
161
|
+
"""Initialize the UpDay Bool indicator.
|
|
162
|
+
|
|
163
|
+
Sets minimum period for boolean up day calculation.
|
|
164
|
+
"""
|
|
165
|
+
super().__init__()
|
|
166
|
+
self.addminperiod(self.p.period + 1)
|
|
167
|
+
|
|
168
|
+
def next(self):
|
|
169
|
+
"""Check if current bar is an up day.
|
|
170
|
+
|
|
171
|
+
Returns 1.0 if close > close_period_ago, 0.0 otherwise.
|
|
172
|
+
"""
|
|
173
|
+
self.lines.upday[0] = 1.0 if self.data[0] > self.data[-self.p.period] else 0.0
|
|
174
|
+
|
|
175
|
+
def once(self, start, end):
|
|
176
|
+
"""Check for up days in runonce mode.
|
|
177
|
+
|
|
178
|
+
Returns 1.0 where price increased, 0.0 otherwise.
|
|
179
|
+
"""
|
|
180
|
+
darray = self.data.array
|
|
181
|
+
larray = self.lines.upday.array
|
|
182
|
+
period = self.p.period
|
|
183
|
+
|
|
184
|
+
while len(larray) < end:
|
|
185
|
+
larray.append(0.0)
|
|
186
|
+
|
|
187
|
+
for i in range(min(period, end, len(larray))):
|
|
188
|
+
larray[i] = 0.0
|
|
189
|
+
|
|
190
|
+
for i in range(period, min(end, len(darray))):
|
|
191
|
+
larray[i] = 1.0 if darray[i] > darray[i - period] else 0.0
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
class DownDayBool(Indicator):
|
|
195
|
+
"""
|
|
196
|
+
Defined by J. Welles Wilder, Jr. in 1978 in his book *"New Concepts in
|
|
197
|
+
Technical Trading Systems"* for the RSI
|
|
198
|
+
|
|
199
|
+
Records days which have been "down", i.e.: the close price has been
|
|
200
|
+
lower than the day before.
|
|
201
|
+
|
|
202
|
+
Note:
|
|
203
|
+
- This version returns a bool rather than the difference
|
|
204
|
+
|
|
205
|
+
Formula:
|
|
206
|
+
- downday = close_prev > close
|
|
207
|
+
|
|
208
|
+
See:
|
|
209
|
+
- http://en.wikipedia.org/wiki/Relative_strength_index
|
|
210
|
+
"""
|
|
211
|
+
|
|
212
|
+
lines = ("downday",)
|
|
213
|
+
params = (("period", 1),)
|
|
214
|
+
|
|
215
|
+
def __init__(self):
|
|
216
|
+
"""Initialize the DownDay Bool indicator.
|
|
217
|
+
|
|
218
|
+
Sets minimum period for boolean down day calculation.
|
|
219
|
+
"""
|
|
220
|
+
super().__init__()
|
|
221
|
+
self.addminperiod(self.p.period + 1)
|
|
222
|
+
|
|
223
|
+
def next(self):
|
|
224
|
+
"""Check if current bar is a down day.
|
|
225
|
+
|
|
226
|
+
Returns 1.0 if close_period_ago > close, 0.0 otherwise.
|
|
227
|
+
"""
|
|
228
|
+
self.lines.downday[0] = 1.0 if self.data[-self.p.period] > self.data[0] else 0.0
|
|
229
|
+
|
|
230
|
+
def once(self, start, end):
|
|
231
|
+
"""Check for down days in runonce mode.
|
|
232
|
+
|
|
233
|
+
Returns 1.0 where price decreased, 0.0 otherwise.
|
|
234
|
+
"""
|
|
235
|
+
darray = self.data.array
|
|
236
|
+
larray = self.lines.downday.array
|
|
237
|
+
period = self.p.period
|
|
238
|
+
|
|
239
|
+
while len(larray) < end:
|
|
240
|
+
larray.append(0.0)
|
|
241
|
+
|
|
242
|
+
for i in range(min(period, end, len(larray))):
|
|
243
|
+
larray[i] = 0.0
|
|
244
|
+
|
|
245
|
+
for i in range(period, min(end, len(darray))):
|
|
246
|
+
larray[i] = 1.0 if darray[i - period] > darray[i] else 0.0
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
class RelativeStrengthIndex(Indicator):
|
|
250
|
+
"""Defined by J. Welles Wilder, Jr. in 1978 in his book *"New Concepts in
|
|
251
|
+
Technical Trading Systems"*.
|
|
252
|
+
|
|
253
|
+
It measures momentum by calculating the ration of higher closes and
|
|
254
|
+
lower closes after having been smoothed by an average, normalizing
|
|
255
|
+
the result between 0 and 100
|
|
256
|
+
|
|
257
|
+
Formula:
|
|
258
|
+
- up = upday(data)
|
|
259
|
+
- down = downday(data)
|
|
260
|
+
- maup = movingaverage(up, period)
|
|
261
|
+
- madown = movingaverage(down, period)
|
|
262
|
+
- rs = maup / madown
|
|
263
|
+
- rsi = 100 - 100 / (1 + rs)
|
|
264
|
+
|
|
265
|
+
The moving average used is the one originally defined by Wilder,
|
|
266
|
+
the SmoothedMovingAverage
|
|
267
|
+
|
|
268
|
+
See:
|
|
269
|
+
- http://en.wikipedia.org/wiki/Relative_strength_index
|
|
270
|
+
|
|
271
|
+
Notes:
|
|
272
|
+
- ``safediv`` (default: False) If this parameter is True, the division
|
|
273
|
+
rs = maup / madown will be checked for the special cases in which a
|
|
274
|
+
``0 / 0`` or ``x / 0`` division will happen
|
|
275
|
+
|
|
276
|
+
- ``safehigh`` (default: 100.0) will be used as RSI value for the
|
|
277
|
+
``x / 0`` case
|
|
278
|
+
|
|
279
|
+
- ``safelow`` (default: 50.0) will be used as RSI value for the
|
|
280
|
+
``0 / 0`` case
|
|
281
|
+
"""
|
|
282
|
+
|
|
283
|
+
alias = (
|
|
284
|
+
"RSI",
|
|
285
|
+
"RSI_SMMA",
|
|
286
|
+
"RSI_Wilder",
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
lines = ("rsi",)
|
|
290
|
+
params = (
|
|
291
|
+
("period", 14),
|
|
292
|
+
("movav", MovAv.Smoothed),
|
|
293
|
+
("upperband", 70.0),
|
|
294
|
+
("lowerband", 30.0),
|
|
295
|
+
("safediv", False),
|
|
296
|
+
("safehigh", 100.0),
|
|
297
|
+
("safelow", 50.0),
|
|
298
|
+
("lookback", 1),
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
def _plotlabel(self):
|
|
302
|
+
plabels = [self.p.period]
|
|
303
|
+
plabels += [self.p.movav] * self.p.notdefault("movav")
|
|
304
|
+
plabels += [self.p.lookback] * self.p.notdefault("lookback")
|
|
305
|
+
return plabels
|
|
306
|
+
|
|
307
|
+
def _plotinit(self):
|
|
308
|
+
self.plotinfo.plotyhlines = [self.p.upperband, self.p.lowerband]
|
|
309
|
+
|
|
310
|
+
def __init__(self):
|
|
311
|
+
"""Initialize the RSI indicator.
|
|
312
|
+
|
|
313
|
+
Creates up/down day indicators and their moving averages.
|
|
314
|
+
"""
|
|
315
|
+
super().__init__()
|
|
316
|
+
self.upday = UpDay(self.data, period=self.p.lookback)
|
|
317
|
+
self.downday = DownDay(self.data, period=self.p.lookback)
|
|
318
|
+
self.maup = self.p.movav(self.upday, period=self.p.period)
|
|
319
|
+
self.madown = self.p.movav(self.downday, period=self.p.period)
|
|
320
|
+
|
|
321
|
+
def _rscalc(self, rsi):
|
|
322
|
+
"""Calculate relative strength from RSI value."""
|
|
323
|
+
try:
|
|
324
|
+
rs = (-100.0 / (rsi - 100.0)) - 1.0
|
|
325
|
+
except ZeroDivisionError:
|
|
326
|
+
return float("inf")
|
|
327
|
+
return rs
|
|
328
|
+
|
|
329
|
+
def _calc_rsi(self, maup_val, madown_val):
|
|
330
|
+
"""Calculate RSI from maup and madown values.
|
|
331
|
+
|
|
332
|
+
Args:
|
|
333
|
+
maup_val: Moving average of up days.
|
|
334
|
+
madown_val: Moving average of down days.
|
|
335
|
+
|
|
336
|
+
Returns:
|
|
337
|
+
RSI value between 0 and 100.
|
|
338
|
+
"""
|
|
339
|
+
if self.p.safediv:
|
|
340
|
+
if madown_val == 0.0:
|
|
341
|
+
if maup_val == 0.0:
|
|
342
|
+
return self.p.safelow # 0/0 case
|
|
343
|
+
return self.p.safehigh # x/0 case
|
|
344
|
+
|
|
345
|
+
if madown_val == 0.0:
|
|
346
|
+
return 100.0 # Avoid division by zero
|
|
347
|
+
|
|
348
|
+
rs = maup_val / madown_val
|
|
349
|
+
return 100.0 - 100.0 / (1.0 + rs)
|
|
350
|
+
|
|
351
|
+
def next(self):
|
|
352
|
+
"""Calculate RSI for the current bar.
|
|
353
|
+
|
|
354
|
+
RSI = 100 - 100 / (1 + maup/madown)
|
|
355
|
+
"""
|
|
356
|
+
self.lines.rsi[0] = self._calc_rsi(self.maup[0], self.madown[0])
|
|
357
|
+
|
|
358
|
+
def once(self, start, end):
|
|
359
|
+
"""Calculate RSI in runonce mode.
|
|
360
|
+
|
|
361
|
+
Computes RSI values across all bars with safe division handling.
|
|
362
|
+
"""
|
|
363
|
+
for child in (self.upday, self.downday, self.maup, self.madown):
|
|
364
|
+
if hasattr(child, "once"):
|
|
365
|
+
child.once(0, end)
|
|
366
|
+
|
|
367
|
+
maup_array = self.maup.lines[0].array
|
|
368
|
+
madown_array = self.madown.lines[0].array
|
|
369
|
+
larray = self.lines.rsi.array
|
|
370
|
+
safediv = self.p.safediv
|
|
371
|
+
safehigh = self.p.safehigh
|
|
372
|
+
safelow = self.p.safelow
|
|
373
|
+
|
|
374
|
+
while len(larray) < end:
|
|
375
|
+
larray.append(float("nan"))
|
|
376
|
+
|
|
377
|
+
for i in range(start, min(end, len(maup_array), len(madown_array))):
|
|
378
|
+
maup_val = maup_array[i] if i < len(maup_array) else 0.0
|
|
379
|
+
madown_val = madown_array[i] if i < len(madown_array) else 0.0
|
|
380
|
+
|
|
381
|
+
if (
|
|
382
|
+
isinstance(maup_val, float)
|
|
383
|
+
and math.isnan(maup_val)
|
|
384
|
+
or isinstance(madown_val, float)
|
|
385
|
+
and math.isnan(madown_val)
|
|
386
|
+
):
|
|
387
|
+
larray[i] = float("nan")
|
|
388
|
+
else:
|
|
389
|
+
if safediv:
|
|
390
|
+
if madown_val == 0.0:
|
|
391
|
+
if maup_val == 0.0:
|
|
392
|
+
larray[i] = safelow
|
|
393
|
+
else:
|
|
394
|
+
larray[i] = safehigh
|
|
395
|
+
continue
|
|
396
|
+
|
|
397
|
+
if madown_val == 0.0:
|
|
398
|
+
larray[i] = 100.0
|
|
399
|
+
else:
|
|
400
|
+
rs = maup_val / madown_val
|
|
401
|
+
larray[i] = 100.0 - 100.0 / (1.0 + rs)
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
RSI = RelativeStrengthIndex
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
class RSI_Safe(RSI):
|
|
408
|
+
"""
|
|
409
|
+
Subclass of RSI which changes parameers ``safediv`` to ``True`` as the
|
|
410
|
+
default value
|
|
411
|
+
|
|
412
|
+
See:
|
|
413
|
+
- http://en.wikipedia.org/wiki/Relative_strength_index
|
|
414
|
+
"""
|
|
415
|
+
|
|
416
|
+
params = (("safediv", True),)
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
class RSI_SMA(RSI):
|
|
420
|
+
"""
|
|
421
|
+
Uses a SimpleMovingAverage as described in Wikipedia and other soures
|
|
422
|
+
|
|
423
|
+
See:
|
|
424
|
+
- http://en.wikipedia.org/wiki/Relative_strength_index
|
|
425
|
+
"""
|
|
426
|
+
|
|
427
|
+
alias = ("RSI_Cutler",)
|
|
428
|
+
|
|
429
|
+
params = (("movav", MovAv.Simple),)
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
class RSI_EMA(RSI):
|
|
433
|
+
"""
|
|
434
|
+
Uses an ExponentialMovingAverage as described in Wikipedia
|
|
435
|
+
|
|
436
|
+
See:
|
|
437
|
+
- http://en.wikipedia.org/wiki/Relative_strength_index
|
|
438
|
+
"""
|
|
439
|
+
|
|
440
|
+
params = (("movav", MovAv.Exponential),)
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""SMA Indicator Module - Simple Moving Average.
|
|
3
|
+
|
|
4
|
+
This module provides the SMA (Simple Moving Average) indicator for
|
|
5
|
+
calculating the non-weighted average of the last n periods.
|
|
6
|
+
|
|
7
|
+
Classes:
|
|
8
|
+
MovingAverageSimple: SMA indicator (alias: SMA).
|
|
9
|
+
|
|
10
|
+
Example:
|
|
11
|
+
class MyStrategy(bt.Strategy):
|
|
12
|
+
def __init__(self):
|
|
13
|
+
self.sma = bt.indicators.SMA(self.data.close, period=20)
|
|
14
|
+
|
|
15
|
+
def next(self):
|
|
16
|
+
if self.data.close[0] > self.sma[0]:
|
|
17
|
+
self.buy()
|
|
18
|
+
elif self.data.close[0] < self.sma[0]:
|
|
19
|
+
self.sell()
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
import math
|
|
23
|
+
|
|
24
|
+
from ..utils.log_message import get_logger
|
|
25
|
+
from .mabase import MovingAverageBase
|
|
26
|
+
|
|
27
|
+
logger = get_logger(__name__)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# Moving average indicator
|
|
31
|
+
class MovingAverageSimple(MovingAverageBase):
|
|
32
|
+
"""
|
|
33
|
+
Non-weighted average of the last n periods
|
|
34
|
+
|
|
35
|
+
Formula:
|
|
36
|
+
- movav = Sum(data, period) / period
|
|
37
|
+
|
|
38
|
+
See also:
|
|
39
|
+
- http://en.wikipedia.org/wiki/Moving_average#Simple_moving_average
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
alias = (
|
|
43
|
+
"SMA",
|
|
44
|
+
"SimpleMovingAverage",
|
|
45
|
+
)
|
|
46
|
+
lines = ("sma",)
|
|
47
|
+
|
|
48
|
+
def __init__(self):
|
|
49
|
+
"""Initialize the SMA indicator."""
|
|
50
|
+
# Before super to ensure mixins (right-hand side in subclassing)
|
|
51
|
+
# can see the assignment operation and operate on the line
|
|
52
|
+
super().__init__()
|
|
53
|
+
self._period = self.p.period
|
|
54
|
+
self._next_offsets = tuple(range(1 - self._period, 1))
|
|
55
|
+
data = getattr(self, "data", None)
|
|
56
|
+
self._data_getitem = data.__getitem__ if data is not None else None
|
|
57
|
+
self._data_get = data.get if data is not None else None
|
|
58
|
+
self._sma_line = self.lines.sma
|
|
59
|
+
self._fsum = math.fsum
|
|
60
|
+
|
|
61
|
+
def nextstart(self):
|
|
62
|
+
"""Initialize on first call after minperiod is met."""
|
|
63
|
+
# Delegate to next() — at this point we have exactly enough data
|
|
64
|
+
self.next()
|
|
65
|
+
|
|
66
|
+
def next(self):
|
|
67
|
+
"""Calculate SMA for the current bar.
|
|
68
|
+
|
|
69
|
+
Recalculates from scratch each bar using sum of the last 'period'
|
|
70
|
+
values to avoid floating-point drift from incremental updates.
|
|
71
|
+
"""
|
|
72
|
+
try:
|
|
73
|
+
data_get = self._data_get
|
|
74
|
+
if data_get is None:
|
|
75
|
+
data = self.data
|
|
76
|
+
data_get = data.get
|
|
77
|
+
self._data_get = data_get
|
|
78
|
+
self._data_getitem = data.__getitem__
|
|
79
|
+
|
|
80
|
+
prices = data_get(size=self._period)
|
|
81
|
+
if len(prices) != self._period:
|
|
82
|
+
data_getitem = self._data_getitem
|
|
83
|
+
if data_getitem is None:
|
|
84
|
+
data_getitem = self.data.__getitem__
|
|
85
|
+
self._data_getitem = data_getitem
|
|
86
|
+
prices = [float(data_getitem(i)) for i in self._next_offsets]
|
|
87
|
+
self._sma_line[0] = self._fsum(prices) / self._period
|
|
88
|
+
except (AttributeError, ValueError, TypeError, IndexError):
|
|
89
|
+
logger.debug("SMA next() failed", exc_info=True)
|
|
90
|
+
self._sma_line[0] = float("nan")
|
|
91
|
+
|
|
92
|
+
def once(self, start, end):
|
|
93
|
+
"""Batch calculation for runonce mode."""
|
|
94
|
+
try:
|
|
95
|
+
# If data source is a LinesOperation, ensure its once() is called first
|
|
96
|
+
if hasattr(self.data, "once") and hasattr(self.data, "operation"):
|
|
97
|
+
try:
|
|
98
|
+
self.data.once(start, end)
|
|
99
|
+
except Exception as e:
|
|
100
|
+
logger.debug("data.once() failed in SMA: %s", e)
|
|
101
|
+
|
|
102
|
+
dst = self.lines[0].array
|
|
103
|
+
src = self.data.array
|
|
104
|
+
period = self.p.period
|
|
105
|
+
actual_end = min(end, len(src))
|
|
106
|
+
|
|
107
|
+
# Ensure destination array is large enough, pre-fill with NaN
|
|
108
|
+
while len(dst) < end:
|
|
109
|
+
dst.append(float("nan"))
|
|
110
|
+
|
|
111
|
+
# Pre-fill warmup period with NaN
|
|
112
|
+
for i in range(min(period - 1, len(src))):
|
|
113
|
+
dst[i] = float("nan")
|
|
114
|
+
|
|
115
|
+
calc_start = max(period - 1, start)
|
|
116
|
+
fsum = math.fsum # Cache function reference
|
|
117
|
+
nan_val = float("nan")
|
|
118
|
+
|
|
119
|
+
for i in range(calc_start, actual_end):
|
|
120
|
+
start_idx = i - period + 1
|
|
121
|
+
end_idx = i + 1
|
|
122
|
+
if end_idx <= len(src):
|
|
123
|
+
window = src[start_idx:end_idx]
|
|
124
|
+
# NaN check: only NaN != NaN (faster than isinstance + isnan)
|
|
125
|
+
has_nan = False
|
|
126
|
+
for v in window:
|
|
127
|
+
if v != v:
|
|
128
|
+
has_nan = True
|
|
129
|
+
break
|
|
130
|
+
if has_nan:
|
|
131
|
+
dst[i] = nan_val
|
|
132
|
+
else:
|
|
133
|
+
dst[i] = fsum(window) / period
|
|
134
|
+
else:
|
|
135
|
+
dst[i] = nan_val
|
|
136
|
+
except Exception:
|
|
137
|
+
logger.debug("SMA once() failed, falling back to once_via_next", exc_info=True)
|
|
138
|
+
super().once_via_next(start, end)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
SMA = MovingAverageSimple
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""SMMA Indicator Module - Smoothed Moving Average.
|
|
3
|
+
|
|
4
|
+
This module provides the SMMA (Smoothed Moving Average) indicator used
|
|
5
|
+
by J. Welles Wilder in his 1978 book.
|
|
6
|
+
|
|
7
|
+
Classes:
|
|
8
|
+
SmoothedMovingAverage: SMMA indicator (aliases: SMMA, WilderMA,
|
|
9
|
+
MovingAverageSmoothed, MovingAverageWilder, ModifiedMovingAverage).
|
|
10
|
+
|
|
11
|
+
Example:
|
|
12
|
+
class MyStrategy(bt.Strategy):
|
|
13
|
+
def __init__(self):
|
|
14
|
+
self.smma = bt.indicators.SMMA(self.data.close, period=14)
|
|
15
|
+
|
|
16
|
+
def next(self):
|
|
17
|
+
if self.data.close[0] > self.smma[0]:
|
|
18
|
+
self.buy()
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from . import MovingAverageBase
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class SmoothedMovingAverage(MovingAverageBase):
|
|
25
|
+
"""
|
|
26
|
+
Smoothing Moving Average used by Wilder in his 1978 book `New Concepts in
|
|
27
|
+
Technical Trading`
|
|
28
|
+
|
|
29
|
+
Defined in his book originally as:
|
|
30
|
+
|
|
31
|
+
- new_value = (old_value * (period - 1) + new_data) / period
|
|
32
|
+
|
|
33
|
+
It Can be expressed as a SmoothingMovingAverage with the following factors:
|
|
34
|
+
|
|
35
|
+
- self.smfactor -> 1.0 / period
|
|
36
|
+
- self.smfactor1 -> `1.0 - self.smfactor`
|
|
37
|
+
|
|
38
|
+
Formula:
|
|
39
|
+
- movav = prev * (1.0 - smoothfactor) + newdata * smoothfactor
|
|
40
|
+
|
|
41
|
+
See also:
|
|
42
|
+
- http://en.wikipedia.org/wiki/Moving_average#Modified_moving_average
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
alias = (
|
|
46
|
+
"SMMA",
|
|
47
|
+
"WilderMA",
|
|
48
|
+
"MovingAverageSmoothed",
|
|
49
|
+
"MovingAverageWilder",
|
|
50
|
+
"ModifiedMovingAverage",
|
|
51
|
+
)
|
|
52
|
+
lines = ("smma",)
|
|
53
|
+
|
|
54
|
+
def __init__(self):
|
|
55
|
+
"""Initialize the SMMA indicator.
|
|
56
|
+
|
|
57
|
+
Calculates alpha and alpha1 smoothing factors for the
|
|
58
|
+
smoothed moving average calculation.
|
|
59
|
+
"""
|
|
60
|
+
super().__init__()
|
|
61
|
+
self.alpha = 1.0 / self.p.period
|
|
62
|
+
self.alpha1 = 1.0 - self.alpha
|
|
63
|
+
|
|
64
|
+
def nextstart(self):
|
|
65
|
+
"""Seed SMMA calculation with SMA on first valid bar.
|
|
66
|
+
|
|
67
|
+
Initializes with simple moving average of the first period values.
|
|
68
|
+
"""
|
|
69
|
+
# Seed value: SMA of first period values
|
|
70
|
+
period = self.p.period
|
|
71
|
+
data_sum = 0.0
|
|
72
|
+
for i in range(period):
|
|
73
|
+
data_sum += self.data[-i]
|
|
74
|
+
self.lines[0][0] = data_sum / period
|
|
75
|
+
|
|
76
|
+
def next(self):
|
|
77
|
+
"""Calculate SMMA for the current bar.
|
|
78
|
+
|
|
79
|
+
Formula: SMMA = prev_SMMMA * alpha1 + current_price * alpha
|
|
80
|
+
where alpha = 1/period and alpha1 = 1 - alpha.
|
|
81
|
+
"""
|
|
82
|
+
# SMMA formula: prev * alpha1 + current * alpha
|
|
83
|
+
self.lines[0][0] = self.lines[0][-1] * self.alpha1 + self.data[0] * self.alpha
|
|
84
|
+
|
|
85
|
+
def once(self, start, end):
|
|
86
|
+
"""Calculate SMMA in runonce mode"""
|
|
87
|
+
darray = self.data.array
|
|
88
|
+
larray = self.lines[0].array
|
|
89
|
+
alpha = self.alpha
|
|
90
|
+
alpha1 = self.alpha1
|
|
91
|
+
period = self.p.period
|
|
92
|
+
|
|
93
|
+
# Ensure output array is properly sized
|
|
94
|
+
while len(larray) < end:
|
|
95
|
+
larray.append(float("nan"))
|
|
96
|
+
|
|
97
|
+
limit = min(end, len(darray))
|
|
98
|
+
for i in range(limit):
|
|
99
|
+
larray[i] = float("nan")
|
|
100
|
+
|
|
101
|
+
# Seed at self._minperiod - 1 to match nextstart() behavior.
|
|
102
|
+
# nextstart() sums self.data[-i] for i in range(period) at the first
|
|
103
|
+
# valid bar, which corresponds to darray[seed_idx - period + 1 : seed_idx + 1].
|
|
104
|
+
seed_idx = self._minperiod - 1
|
|
105
|
+
if seed_idx >= limit or seed_idx < period - 1:
|
|
106
|
+
return
|
|
107
|
+
|
|
108
|
+
seed_start = seed_idx - period + 1
|
|
109
|
+
prev = sum(float(darray[j]) for j in range(seed_start, seed_idx + 1)) / period
|
|
110
|
+
larray[seed_idx] = prev
|
|
111
|
+
|
|
112
|
+
# SMMA is recursive - must calculate ALL values from period onwards
|
|
113
|
+
for i in range(seed_idx + 1, limit):
|
|
114
|
+
current_val = float(darray[i])
|
|
115
|
+
prev = prev * alpha1 + current_val * alpha
|
|
116
|
+
larray[i] = prev
|