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,139 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Functional-test indicators migrated to contrib.
|
|
3
|
+
|
|
4
|
+
Generated from a single functional strategy module to preserve file-local
|
|
5
|
+
helper functions and constants without cross-test name collisions.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .. import (
|
|
9
|
+
ExponentialMovingAverage,
|
|
10
|
+
Indicator,
|
|
11
|
+
SimpleMovingAverage,
|
|
12
|
+
SmoothedMovingAverage,
|
|
13
|
+
WeightedMovingAverage,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"VininITrendIndicator",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def resolve_ma_class(name):
|
|
22
|
+
"""Resolve MA method identifier to a Backtrader MA class.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
name: Method name from configuration.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
Backtrader MA class.
|
|
29
|
+
"""
|
|
30
|
+
mode = str(name).lower()
|
|
31
|
+
if mode in {"sma", "mode_sma"}:
|
|
32
|
+
return SimpleMovingAverage
|
|
33
|
+
if mode in {"ema", "mode_ema"}:
|
|
34
|
+
return ExponentialMovingAverage
|
|
35
|
+
if mode in {"smma", "mode_smma"}:
|
|
36
|
+
return SmoothedMovingAverage
|
|
37
|
+
return WeightedMovingAverage
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def resolve_price_line(data, mode):
|
|
41
|
+
"""Resolve an applied price variant from raw data lines.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
data: Backtrader feed or data object.
|
|
45
|
+
mode: Price selector key.
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
backtrader line: Selected price series.
|
|
49
|
+
"""
|
|
50
|
+
price_mode = str(mode).lower()
|
|
51
|
+
if price_mode in {"price_open", "open"}:
|
|
52
|
+
return data.open
|
|
53
|
+
if price_mode in {"price_high", "high"}:
|
|
54
|
+
return data.high
|
|
55
|
+
if price_mode in {"price_low", "low"}:
|
|
56
|
+
return data.low
|
|
57
|
+
if price_mode in {"price_median", "median"}:
|
|
58
|
+
return (data.high + data.low) / 2.0
|
|
59
|
+
if price_mode in {"price_typical", "typical"}:
|
|
60
|
+
return (data.high + data.low + data.close) / 3.0
|
|
61
|
+
if price_mode in {"price_weighted", "weighted"}:
|
|
62
|
+
return (data.high + data.low + data.close + data.close) / 4.0
|
|
63
|
+
return data.close
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class VininITrendIndicator(Indicator):
|
|
67
|
+
"""Indicator that calculates a smoothed trend score from MA comparisons."""
|
|
68
|
+
|
|
69
|
+
lines = ("trend",)
|
|
70
|
+
params = (
|
|
71
|
+
("ma_method1", "sma"),
|
|
72
|
+
("length1", 3),
|
|
73
|
+
("phase1", 15),
|
|
74
|
+
("ma_step", 10),
|
|
75
|
+
("ma_count", 10),
|
|
76
|
+
("ma_method2", "jjma"),
|
|
77
|
+
("length2", 20),
|
|
78
|
+
("phase2", 100),
|
|
79
|
+
("ipc", "price_close"),
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
def __init__(self):
|
|
83
|
+
"""Build MA lines and required warmup length."""
|
|
84
|
+
price_line = resolve_price_line(self.data, self.p.ipc)
|
|
85
|
+
periods = [
|
|
86
|
+
int(self.p.length1 + idx * self.p.ma_step) for idx in range(int(self.p.ma_count))
|
|
87
|
+
]
|
|
88
|
+
self._ma_lines = [
|
|
89
|
+
resolve_ma_class(self.p.ma_method1)(price_line, period=max(1, p)) for p in periods
|
|
90
|
+
]
|
|
91
|
+
self._smooth = resolve_ma_class(self.p.ma_method2)(
|
|
92
|
+
self.lines.trend, period=max(1, int(self.p.length2))
|
|
93
|
+
)
|
|
94
|
+
self.addminperiod(max(periods) + int(self.p.length2) + 5)
|
|
95
|
+
|
|
96
|
+
def next(self):
|
|
97
|
+
"""Compute trend score and one-step EMA-smoothed trend value."""
|
|
98
|
+
close_value = float(self.data.close[0])
|
|
99
|
+
score = 0
|
|
100
|
+
for ma_line in self._ma_lines:
|
|
101
|
+
if close_value > float(ma_line[0]):
|
|
102
|
+
score += 1
|
|
103
|
+
else:
|
|
104
|
+
score -= 1
|
|
105
|
+
raw = 100.0 * score / max(1, len(self._ma_lines))
|
|
106
|
+
prev = float(self.lines.trend[-1]) if len(self) > 0 else raw
|
|
107
|
+
if prev != prev:
|
|
108
|
+
prev = raw
|
|
109
|
+
period = max(1, int(self.p.length2))
|
|
110
|
+
alpha = 2.0 / (period + 1.0)
|
|
111
|
+
if len(self) == 0:
|
|
112
|
+
self.lines.trend[0] = raw
|
|
113
|
+
else:
|
|
114
|
+
self.lines.trend[0] = alpha * raw + (1.0 - alpha) * prev
|
|
115
|
+
|
|
116
|
+
def once(self, start, end):
|
|
117
|
+
"""Compute trend values for startup/backfill path."""
|
|
118
|
+
close_array = self.data.close.array
|
|
119
|
+
ma_arrays = [ma_line.array for ma_line in self._ma_lines]
|
|
120
|
+
trend_line = self.lines.trend.array
|
|
121
|
+
while len(trend_line) < end:
|
|
122
|
+
trend_line.append(float("nan"))
|
|
123
|
+
|
|
124
|
+
period = max(1, int(self.p.length2))
|
|
125
|
+
alpha = 2.0 / (period + 1.0)
|
|
126
|
+
prev = None
|
|
127
|
+
actual_end = min([end, len(close_array)] + [len(array) for array in ma_arrays])
|
|
128
|
+
for i in range(start, actual_end):
|
|
129
|
+
close_value = float(close_array[i])
|
|
130
|
+
score = 0
|
|
131
|
+
for ma_array in ma_arrays:
|
|
132
|
+
if close_value > float(ma_array[i]):
|
|
133
|
+
score += 1
|
|
134
|
+
else:
|
|
135
|
+
score -= 1
|
|
136
|
+
raw = 100.0 * score / max(1, len(ma_arrays))
|
|
137
|
+
value = raw if prev is None else alpha * raw + (1.0 - alpha) * prev
|
|
138
|
+
trend_line[i] = value
|
|
139
|
+
prev = value
|
|
@@ -0,0 +1,78 @@
|
|
|
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
|
+
"VolumeWeightedMAIndicator",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _applied_price(data, price_type, ago=0):
|
|
16
|
+
o = float(data.open[-ago])
|
|
17
|
+
h = float(data.high[-ago])
|
|
18
|
+
low_price = float(data.low[-ago])
|
|
19
|
+
c = float(data.close[-ago])
|
|
20
|
+
if price_type == 0:
|
|
21
|
+
return c
|
|
22
|
+
if price_type == 1:
|
|
23
|
+
return o
|
|
24
|
+
if price_type == 2:
|
|
25
|
+
return h
|
|
26
|
+
if price_type == 3:
|
|
27
|
+
return low_price
|
|
28
|
+
if price_type == 4:
|
|
29
|
+
return (h + low_price) / 2.0
|
|
30
|
+
if price_type == 5:
|
|
31
|
+
return (h + low_price + c) / 3.0
|
|
32
|
+
if price_type == 6:
|
|
33
|
+
return (h + low_price + c + c) / 4.0
|
|
34
|
+
return c
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class VolumeWeightedMAIndicator(Indicator):
|
|
38
|
+
"""Volume-weighted moving average of an applied price.
|
|
39
|
+
|
|
40
|
+
Averages the applied price (selected by ``ipc``) over ``length`` bars,
|
|
41
|
+
weighting each bar by its tick volume (or open interest when
|
|
42
|
+
``use_tick_volume`` is False); falls back to the plain applied price when
|
|
43
|
+
the total weight is zero.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
lines = ("vwma",)
|
|
47
|
+
params = (
|
|
48
|
+
("length", 12),
|
|
49
|
+
("ipc", 0),
|
|
50
|
+
("use_tick_volume", True),
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
def __init__(self):
|
|
54
|
+
"""Set the minimum period to cover the averaging window."""
|
|
55
|
+
self.addminperiod(int(self.p.length) + 2)
|
|
56
|
+
|
|
57
|
+
def next(self):
|
|
58
|
+
"""Compute the volume-weighted average price for the current bar."""
|
|
59
|
+
length = int(self.p.length)
|
|
60
|
+
weights = []
|
|
61
|
+
total = 0.0
|
|
62
|
+
for i in range(length):
|
|
63
|
+
vol = (
|
|
64
|
+
float(self.data.volume[-i])
|
|
65
|
+
if self.p.use_tick_volume
|
|
66
|
+
else float(self.data.openinterest[-i])
|
|
67
|
+
)
|
|
68
|
+
if vol < 0:
|
|
69
|
+
vol = 0.0
|
|
70
|
+
weights.append(vol)
|
|
71
|
+
total += vol
|
|
72
|
+
if total == 0.0:
|
|
73
|
+
self.lines.vwma[0] = _applied_price(self.data, int(self.p.ipc), 0)
|
|
74
|
+
return
|
|
75
|
+
value = 0.0
|
|
76
|
+
for i in range(length):
|
|
77
|
+
value += _applied_price(self.data, int(self.p.ipc), i) * (weights[i] / total)
|
|
78
|
+
self.lines.vwma[0] = value
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Functional-test indicators migrated to contrib.
|
|
3
|
+
|
|
4
|
+
Generated from a single functional strategy module to preserve file-local
|
|
5
|
+
helper functions and constants without cross-test name collisions.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import math
|
|
9
|
+
|
|
10
|
+
from .. import Indicator
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"VolumeWeightedMAStDevIndicator",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _applied_price(data, price_type, ago=0):
|
|
18
|
+
o = float(data.open[-ago])
|
|
19
|
+
h = float(data.high[-ago])
|
|
20
|
+
low_price = float(data.low[-ago])
|
|
21
|
+
c = float(data.close[-ago])
|
|
22
|
+
if price_type == 0:
|
|
23
|
+
return c
|
|
24
|
+
if price_type == 1:
|
|
25
|
+
return o
|
|
26
|
+
if price_type == 2:
|
|
27
|
+
return h
|
|
28
|
+
if price_type == 3:
|
|
29
|
+
return low_price
|
|
30
|
+
if price_type == 4:
|
|
31
|
+
return (h + low_price) / 2.0
|
|
32
|
+
if price_type == 5:
|
|
33
|
+
return (h + low_price + c) / 3.0
|
|
34
|
+
if price_type == 6:
|
|
35
|
+
return (h + low_price + c + c) / 4.0
|
|
36
|
+
return c
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class VolumeWeightedMAStDevIndicator(Indicator):
|
|
40
|
+
"""Volume-weighted MA with standard-deviation graded signal lines.
|
|
41
|
+
|
|
42
|
+
Computes a volume-weighted moving average (``vwma``) and measures the
|
|
43
|
+
standard deviation of its change. When the latest change exceeds the
|
|
44
|
+
``dk1``/``dk2`` standard-deviation bands it sets the corresponding
|
|
45
|
+
``bulls1``/``bulls2`` or ``bears1``/``bears2`` signal lines.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
lines = ("vwma", "bears1", "bulls1", "bears2", "bulls2")
|
|
49
|
+
params = (
|
|
50
|
+
("length", 12),
|
|
51
|
+
("ipc", 0),
|
|
52
|
+
("use_tick_volume", True),
|
|
53
|
+
("dk1", 1.5),
|
|
54
|
+
("dk2", 2.5),
|
|
55
|
+
("std_period", 9),
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
def __init__(self):
|
|
59
|
+
"""Reserve the warm-up window for the VWMA and std-dev calculations."""
|
|
60
|
+
self.addminperiod(int(self.p.length) + int(self.p.std_period) + 3)
|
|
61
|
+
|
|
62
|
+
def _vwma_at(self, ago):
|
|
63
|
+
length = int(self.p.length)
|
|
64
|
+
weights = []
|
|
65
|
+
total = 0.0
|
|
66
|
+
for i in range(length):
|
|
67
|
+
idx = ago + i
|
|
68
|
+
vol = (
|
|
69
|
+
float(self.data.volume[-idx])
|
|
70
|
+
if self.p.use_tick_volume
|
|
71
|
+
else float(self.data.openinterest[-idx])
|
|
72
|
+
)
|
|
73
|
+
if vol < 0:
|
|
74
|
+
vol = 0.0
|
|
75
|
+
weights.append(vol)
|
|
76
|
+
total += vol
|
|
77
|
+
if total == 0.0:
|
|
78
|
+
return _applied_price(self.data, int(self.p.ipc), ago)
|
|
79
|
+
value = 0.0
|
|
80
|
+
for i in range(length):
|
|
81
|
+
value += _applied_price(self.data, int(self.p.ipc), ago + i) * (weights[i] / total)
|
|
82
|
+
return value
|
|
83
|
+
|
|
84
|
+
def next(self):
|
|
85
|
+
"""Update the VWMA and set graded bull/bear signal lines."""
|
|
86
|
+
self.lines.bears1[0] = float("nan")
|
|
87
|
+
self.lines.bulls1[0] = float("nan")
|
|
88
|
+
self.lines.bears2[0] = float("nan")
|
|
89
|
+
self.lines.bulls2[0] = float("nan")
|
|
90
|
+
vwma_now = self._vwma_at(0)
|
|
91
|
+
self.lines.vwma[0] = vwma_now
|
|
92
|
+
std_period = int(self.p.std_period)
|
|
93
|
+
dvwma = []
|
|
94
|
+
for i in range(std_period):
|
|
95
|
+
v0 = self._vwma_at(i)
|
|
96
|
+
v1 = self._vwma_at(i + 1)
|
|
97
|
+
dvwma.append(v0 - v1)
|
|
98
|
+
mean = sum(dvwma) / std_period
|
|
99
|
+
variance = sum((x - mean) ** 2 for x in dvwma) / std_period
|
|
100
|
+
stdev = math.sqrt(variance)
|
|
101
|
+
dstd = dvwma[0]
|
|
102
|
+
filter1 = float(self.p.dk1) * stdev
|
|
103
|
+
filter2 = float(self.p.dk2) * stdev
|
|
104
|
+
if dstd < -filter1 and dstd >= -filter2:
|
|
105
|
+
self.lines.bears1[0] = vwma_now
|
|
106
|
+
if dstd < -filter2:
|
|
107
|
+
self.lines.bears2[0] = vwma_now
|
|
108
|
+
if dstd > filter1 and dstd <= filter2:
|
|
109
|
+
self.lines.bulls1[0] = vwma_now
|
|
110
|
+
if dstd > filter2:
|
|
111
|
+
self.lines.bulls2[0] = vwma_now
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Functional-test indicators migrated to contrib.
|
|
3
|
+
|
|
4
|
+
Generated from a single functional strategy module to preserve file-local
|
|
5
|
+
helper functions and constants without cross-test name collisions.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import math
|
|
9
|
+
|
|
10
|
+
from .. import Indicator
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"VWAPCloseIndicator",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class VWAPCloseIndicator(Indicator):
|
|
18
|
+
"""Reconstructs VWAP_Close indicator.
|
|
19
|
+
|
|
20
|
+
VWAP = sum(close[i] * volume[i], i=0..n-1) / sum(volume[i], i=0..n-1)
|
|
21
|
+
Uses tick volume by default.
|
|
22
|
+
Buffer 0 = VWAP line.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
lines = ("vwap",)
|
|
26
|
+
params = (("n", 2),)
|
|
27
|
+
|
|
28
|
+
def __init__(self):
|
|
29
|
+
"""Initialize VWAP rolling window size and minimum period.
|
|
30
|
+
|
|
31
|
+
The indicator keeps the latest ``n`` bar prices and volumes and starts
|
|
32
|
+
producing values only after enough history is available.
|
|
33
|
+
"""
|
|
34
|
+
self._n = int(self.p.n)
|
|
35
|
+
self.addminperiod(self._n + 1)
|
|
36
|
+
|
|
37
|
+
def next(self):
|
|
38
|
+
"""Compute and emit the next VWAP-close value.
|
|
39
|
+
|
|
40
|
+
The calculation uses close*volume weighted average over up to ``n`` prior
|
|
41
|
+
bars and falls back to the previous VWAP value when volume is not
|
|
42
|
+
available.
|
|
43
|
+
"""
|
|
44
|
+
n = self._n
|
|
45
|
+
sum1 = 0.0
|
|
46
|
+
sum2 = 0
|
|
47
|
+
for i in range(n):
|
|
48
|
+
if i >= len(self.data):
|
|
49
|
+
break
|
|
50
|
+
c = float(self.data.close[-i])
|
|
51
|
+
v = float(self.data.volume[-i])
|
|
52
|
+
if v < 1:
|
|
53
|
+
v = 1
|
|
54
|
+
sum1 += c * v
|
|
55
|
+
sum2 += v
|
|
56
|
+
|
|
57
|
+
if sum2 > 0:
|
|
58
|
+
self.lines.vwap[0] = sum1 / sum2
|
|
59
|
+
else:
|
|
60
|
+
prev = (
|
|
61
|
+
float(self.lines.vwap[-1])
|
|
62
|
+
if len(self.lines.vwap) > 1
|
|
63
|
+
else float(self.data.close[0])
|
|
64
|
+
)
|
|
65
|
+
self.lines.vwap[0] = prev if not math.isnan(prev) else float(self.data.close[0])
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Functional-test indicators migrated to contrib.
|
|
3
|
+
|
|
4
|
+
Generated from a single functional strategy module to preserve file-local
|
|
5
|
+
helper functions and constants without cross-test name collisions.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .. import Indicator
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"VWMACandle",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class VWMACandle(Indicator):
|
|
16
|
+
"""Volume-weighted candle color indicator.
|
|
17
|
+
|
|
18
|
+
Computes volume-weighted moving averages of the open and close over
|
|
19
|
+
``length`` bars and emits a ``color`` line of 2.0 (bullish), 0.0 (bearish)
|
|
20
|
+
or 1.0 (neutral) depending on their relationship.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
lines = ("color",)
|
|
24
|
+
params = (
|
|
25
|
+
("length", 12),
|
|
26
|
+
("use_tick_volume", True),
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
def __init__(self):
|
|
30
|
+
"""Reserve the warm-up window needed for the volume-weighted average."""
|
|
31
|
+
self.addminperiod(int(self.p.length) + 3)
|
|
32
|
+
|
|
33
|
+
def _vwma(self, field, ago=0):
|
|
34
|
+
length = int(self.p.length)
|
|
35
|
+
total = 0.0
|
|
36
|
+
vals = 0.0
|
|
37
|
+
for i in range(length):
|
|
38
|
+
idx = ago + i
|
|
39
|
+
vol = (
|
|
40
|
+
float(self.data.volume[-idx])
|
|
41
|
+
if self.p.use_tick_volume
|
|
42
|
+
else float(self.data.openinterest[-idx])
|
|
43
|
+
)
|
|
44
|
+
total += max(vol, 0.0)
|
|
45
|
+
vals += float(getattr(self.data, field)[-idx]) * max(vol, 0.0)
|
|
46
|
+
return float(getattr(self.data, field)[-ago]) if total == 0.0 else vals / total
|
|
47
|
+
|
|
48
|
+
def next(self):
|
|
49
|
+
"""Set the candle color from volume-weighted open vs close."""
|
|
50
|
+
op = self._vwma("open", 0)
|
|
51
|
+
cl = self._vwma("close", 0)
|
|
52
|
+
color = 1.0
|
|
53
|
+
if op < cl:
|
|
54
|
+
color = 2.0
|
|
55
|
+
elif op > cl:
|
|
56
|
+
color = 0.0
|
|
57
|
+
self.lines.color[0] = color
|
|
@@ -0,0 +1,70 @@
|
|
|
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
|
+
"VWMADigitSystem",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class VWMADigitSystem(Indicator):
|
|
16
|
+
"""Digit-rounded volume-weighted band color indicator.
|
|
17
|
+
|
|
18
|
+
Builds digit-rounded volume-weighted high and low levels over ``length``
|
|
19
|
+
bars and emits a ``color`` line encoding whether the close breaks above the
|
|
20
|
+
upper level or below the lower level, combined with candle direction.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
lines = ("color",)
|
|
24
|
+
params = (
|
|
25
|
+
("length", 12),
|
|
26
|
+
("digit", 2),
|
|
27
|
+
("shift", 2),
|
|
28
|
+
("use_tick_volume", True),
|
|
29
|
+
("point", 0.01),
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
def __init__(self):
|
|
33
|
+
"""Reserve the warm-up window for the shifted weighted levels."""
|
|
34
|
+
self.addminperiod(int(self.p.length) + int(self.p.shift) + 3)
|
|
35
|
+
|
|
36
|
+
def _weighted_level(self, series_name, ago=0):
|
|
37
|
+
length = int(self.p.length)
|
|
38
|
+
weights = []
|
|
39
|
+
total = 0.0
|
|
40
|
+
for i in range(length):
|
|
41
|
+
idx = ago + i
|
|
42
|
+
vol = (
|
|
43
|
+
float(self.data.volume[-idx])
|
|
44
|
+
if self.p.use_tick_volume
|
|
45
|
+
else float(self.data.openinterest[-idx])
|
|
46
|
+
)
|
|
47
|
+
weights.append(max(vol, 0.0))
|
|
48
|
+
total += max(vol, 0.0)
|
|
49
|
+
if total == 0.0:
|
|
50
|
+
return float(getattr(self.data, series_name)[-ago])
|
|
51
|
+
value = 0.0
|
|
52
|
+
for i in range(length):
|
|
53
|
+
idx = ago + i
|
|
54
|
+
value += float(getattr(self.data, series_name)[-idx]) * (weights[i] / total)
|
|
55
|
+
step = float(self.p.point) * (10 ** int(self.p.digit))
|
|
56
|
+
return round(value / step) * step if step else value
|
|
57
|
+
|
|
58
|
+
def next(self):
|
|
59
|
+
"""Set the band color from close breaks of the weighted levels."""
|
|
60
|
+
shift = int(self.p.shift)
|
|
61
|
+
up = self._weighted_level("high", shift)
|
|
62
|
+
dn = self._weighted_level("low", shift)
|
|
63
|
+
close = float(self.data.close[0])
|
|
64
|
+
open_ = float(self.data.open[0])
|
|
65
|
+
color = 2.0
|
|
66
|
+
if close > up:
|
|
67
|
+
color = 4.0 if open_ < close else 3.0
|
|
68
|
+
if close < dn:
|
|
69
|
+
color = 0.0 if open_ > close else 1.0
|
|
70
|
+
self.lines.color[0] = color
|
|
@@ -0,0 +1,43 @@
|
|
|
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
|
+
"Wami",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Wami(Indicator):
|
|
19
|
+
"""Calculate a WAMI-style oscillator and signal line from close-price MAs."""
|
|
20
|
+
|
|
21
|
+
lines = ("wami", "signal")
|
|
22
|
+
params = (
|
|
23
|
+
("period_ma1", 4),
|
|
24
|
+
("period_ma2", 13),
|
|
25
|
+
("period_ma3", 13),
|
|
26
|
+
("period_sig", 4),
|
|
27
|
+
("point_size", 0.01),
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
def __init__(self):
|
|
31
|
+
"""Initialize WAMI indicator stages and output lines."""
|
|
32
|
+
base_ma = SimpleMovingAverage(self.data.close, period=1)
|
|
33
|
+
diff = base_ma - base_ma(-1)
|
|
34
|
+
ma1 = SimpleMovingAverage(diff, period=self.p.period_ma1)
|
|
35
|
+
ma2 = SimpleMovingAverage(ma1, period=self.p.period_ma2)
|
|
36
|
+
ma3 = SimpleMovingAverage(ma2, period=self.p.period_ma3)
|
|
37
|
+
sig = SimpleMovingAverage(ma3, period=self.p.period_sig)
|
|
38
|
+
scale = self.p.point_size if self.p.point_size else 1.0
|
|
39
|
+
self.lines.wami = ma3 / scale
|
|
40
|
+
self.lines.signal = sig / scale
|
|
41
|
+
self.addminperiod(
|
|
42
|
+
1 + self.p.period_ma1 + self.p.period_ma2 + self.p.period_ma3 + self.p.period_sig
|
|
43
|
+
)
|
|
@@ -0,0 +1,105 @@
|
|
|
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
|
+
"WPRSISignalIndicator",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class WPRSISignalIndicator(Indicator):
|
|
16
|
+
"""Reconstructs WPRSIsignal indicator from its MQ5 source.
|
|
17
|
+
|
|
18
|
+
Uses WPR and RSI with same period.
|
|
19
|
+
Buy: WPR crosses above -20 from below AND RSI > 50, with filterUP lookback confirmation.
|
|
20
|
+
Sell: WPR crosses below -80 from above AND RSI < 50, with filterDN lookback confirmation.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
lines = ("sell_arrow", "buy_arrow") # buffer 0 = sell, buffer 1 = buy
|
|
24
|
+
params = (
|
|
25
|
+
("wprsi_period", 27),
|
|
26
|
+
("filter_up", 10),
|
|
27
|
+
("filter_dn", 10),
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
def __init__(self):
|
|
31
|
+
"""Reserve warm-up bars covering the WPRSI period plus the filter window."""
|
|
32
|
+
self._period = int(self.p.wprsi_period)
|
|
33
|
+
self._filter_up = int(self.p.filter_up)
|
|
34
|
+
self._filter_dn = int(self.p.filter_dn)
|
|
35
|
+
filter_max = max(self._filter_up, self._filter_dn)
|
|
36
|
+
self.addminperiod(self._period + filter_max + 3)
|
|
37
|
+
|
|
38
|
+
def _calc_wpr(self, ago=0):
|
|
39
|
+
period = self._period
|
|
40
|
+
highest = max(float(self.data.high[-(ago + i)]) for i in range(period))
|
|
41
|
+
lowest = min(float(self.data.low[-(ago + i)]) for i in range(period))
|
|
42
|
+
close = float(self.data.close[-ago])
|
|
43
|
+
if highest == lowest:
|
|
44
|
+
return -50.0
|
|
45
|
+
return -100.0 * (highest - close) / (highest - lowest)
|
|
46
|
+
|
|
47
|
+
def _calc_rsi(self, ago=0):
|
|
48
|
+
period = self._period
|
|
49
|
+
gains = 0.0
|
|
50
|
+
losses = 0.0
|
|
51
|
+
for i in range(period):
|
|
52
|
+
idx = ago + i
|
|
53
|
+
c = float(self.data.close[-idx])
|
|
54
|
+
cp = float(self.data.close[-(idx + 1)])
|
|
55
|
+
diff = c - cp
|
|
56
|
+
if diff > 0:
|
|
57
|
+
gains += diff
|
|
58
|
+
else:
|
|
59
|
+
losses -= diff
|
|
60
|
+
avg_gain = gains / period
|
|
61
|
+
avg_loss = losses / period
|
|
62
|
+
if avg_loss == 0:
|
|
63
|
+
return 100.0
|
|
64
|
+
rs = avg_gain / avg_loss
|
|
65
|
+
return 100.0 - (100.0 / (1.0 + rs))
|
|
66
|
+
|
|
67
|
+
def next(self):
|
|
68
|
+
"""Emit buy/sell arrows on filtered Williams %R crosses confirmed by RSI."""
|
|
69
|
+
wpr_0 = self._calc_wpr(0)
|
|
70
|
+
wpr_1 = self._calc_wpr(1)
|
|
71
|
+
rsi_0 = self._calc_rsi(0)
|
|
72
|
+
|
|
73
|
+
buy_val = 0.0
|
|
74
|
+
sell_val = 0.0
|
|
75
|
+
|
|
76
|
+
cur_high = float(self.data.high[0])
|
|
77
|
+
cur_low = float(self.data.low[0])
|
|
78
|
+
rng = cur_high - cur_low
|
|
79
|
+
|
|
80
|
+
# Buy: WPR crosses above -20 from below, RSI > 50
|
|
81
|
+
if wpr_0 > -20.0 and wpr_1 < -20.0 and rsi_0 > 50.0:
|
|
82
|
+
z = 0
|
|
83
|
+
for k in range(2, self._filter_up + 3):
|
|
84
|
+
if k < len(self.data):
|
|
85
|
+
wk = self._calc_wpr(k)
|
|
86
|
+
if wk > -20.0:
|
|
87
|
+
z = 1
|
|
88
|
+
break
|
|
89
|
+
if z == 0:
|
|
90
|
+
buy_val = cur_low - rng / 2.0
|
|
91
|
+
|
|
92
|
+
# Sell: WPR crosses below -80 from above, RSI < 50
|
|
93
|
+
if wpr_1 > -80.0 and wpr_0 < -80.0 and rsi_0 < 50.0:
|
|
94
|
+
h = 0
|
|
95
|
+
for c in range(2, self._filter_dn + 3):
|
|
96
|
+
if c < len(self.data):
|
|
97
|
+
wk = self._calc_wpr(c)
|
|
98
|
+
if wk < -80.0:
|
|
99
|
+
h = 1
|
|
100
|
+
break
|
|
101
|
+
if h == 0:
|
|
102
|
+
sell_val = cur_high + rng / 2.0
|
|
103
|
+
|
|
104
|
+
self.lines.sell_arrow[0] = sell_val
|
|
105
|
+
self.lines.buy_arrow[0] = buy_val
|