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,32 @@
|
|
|
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
|
+
"JTpoProxy",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class JTpoProxy(Indicator):
|
|
19
|
+
"""Proxy oscillator measuring close deviation from its moving average."""
|
|
20
|
+
|
|
21
|
+
lines = ("value",)
|
|
22
|
+
params = (("period", 14),)
|
|
23
|
+
|
|
24
|
+
def __init__(self):
|
|
25
|
+
"""Set up the SMA and minimum period from the period parameter."""
|
|
26
|
+
self.period = max(2, int(self.p.period))
|
|
27
|
+
self.ma = SimpleMovingAverage(self.data.close, period=self.period)
|
|
28
|
+
self.addminperiod(self.period + 1)
|
|
29
|
+
|
|
30
|
+
def next(self):
|
|
31
|
+
"""Compute the current close-minus-SMA deviation value."""
|
|
32
|
+
self.lines.value[0] = float(self.data.close[0]) - float(self.ma[0])
|
|
@@ -0,0 +1,73 @@
|
|
|
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
|
+
If,
|
|
11
|
+
Indicator,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"JMASlopeIndicator",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def resolve_price_line(data, mode):
|
|
20
|
+
"""Return the applied-price line for a data feed given a price mode.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
data: The data feed providing OHLC lines.
|
|
24
|
+
mode: Applied-price selector (e.g. ``price_close``, ``price_median``,
|
|
25
|
+
``price_typical`` or their short forms).
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
A line expression for the selected applied price, defaulting to the
|
|
29
|
+
close for unrecognized modes.
|
|
30
|
+
"""
|
|
31
|
+
price_mode = str(mode).lower()
|
|
32
|
+
if price_mode in {"price_open", "open"}:
|
|
33
|
+
return data.open
|
|
34
|
+
if price_mode in {"price_high", "high"}:
|
|
35
|
+
return data.high
|
|
36
|
+
if price_mode in {"price_low", "low"}:
|
|
37
|
+
return data.low
|
|
38
|
+
if price_mode in {"price_median", "median"}:
|
|
39
|
+
return (data.high + data.low) / 2.0
|
|
40
|
+
if price_mode in {"price_typical", "typical"}:
|
|
41
|
+
return (data.high + data.low + data.close) / 3.0
|
|
42
|
+
if price_mode in {"price_weighted", "weighted"}:
|
|
43
|
+
return (2.0 * data.close + data.high + data.low) / 4.0
|
|
44
|
+
if price_mode in {"price_simpl", "simpl"}:
|
|
45
|
+
return (data.open + data.close) / 2.0
|
|
46
|
+
if price_mode in {"price_quarter", "quarter"}:
|
|
47
|
+
return (data.high + data.low + data.open + data.close) / 4.0
|
|
48
|
+
return data.close
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class JMASlopeIndicator(Indicator):
|
|
52
|
+
"""Slope of a Jurik-style moving average with a rising/falling color.
|
|
53
|
+
|
|
54
|
+
Approximates the JMA with an EMA of the applied price, then exposes its
|
|
55
|
+
bar-over-bar change on the ``value`` line and a ``color`` line marking
|
|
56
|
+
whether the slope is positive (4), negative (0) or flat (2).
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
lines = ("value", "color")
|
|
60
|
+
params = (
|
|
61
|
+
("jlength", 14),
|
|
62
|
+
("jphase", 0),
|
|
63
|
+
("ipc", "price_close"),
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
def __init__(self):
|
|
67
|
+
"""Build the JMA proxy and its slope/color lines; set the min period."""
|
|
68
|
+
price_line = resolve_price_line(self.data, self.p.ipc)
|
|
69
|
+
self._jma = ExponentialMovingAverage(price_line, period=max(1, int(self.p.jlength)))
|
|
70
|
+
delta = self._jma - self._jma(-1)
|
|
71
|
+
self.lines.value = delta
|
|
72
|
+
self.lines.color = If(delta > 0.0, 4.0, If(delta < 0.0, 0.0, 2.0))
|
|
73
|
+
self.addminperiod(32 + int(self.p.jlength))
|
|
@@ -0,0 +1,119 @@
|
|
|
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
|
+
"KalmanFilterIndicator",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
APPLIED_PRICE_MAP = {
|
|
18
|
+
"PRICE_CLOSE": 0,
|
|
19
|
+
"PRICE_OPEN": 1,
|
|
20
|
+
"PRICE_HIGH": 2,
|
|
21
|
+
"PRICE_LOW": 3,
|
|
22
|
+
"PRICE_MEDIAN": 4,
|
|
23
|
+
"PRICE_TYPICAL": 5,
|
|
24
|
+
"PRICE_WEIGHTED": 6,
|
|
25
|
+
"PRICE_OPEN_CLOSE": 8,
|
|
26
|
+
"PRICE_OHLC_AVERAGE": 9,
|
|
27
|
+
"PRICE_DEMARK": 10,
|
|
28
|
+
"PRICE_AVERAGE_DEMARK": 11,
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
SIGNAL_MODE_MAP = {
|
|
33
|
+
"Trend": 0,
|
|
34
|
+
"Kalman": 1,
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class KalmanFilterIndicator(Indicator):
|
|
39
|
+
"""Kalman-style adaptive price filter producing value and direction lines."""
|
|
40
|
+
|
|
41
|
+
lines = ("value", "color_idx")
|
|
42
|
+
params = (
|
|
43
|
+
("k", 1.0),
|
|
44
|
+
("applied_price", "PRICE_WEIGHTED"),
|
|
45
|
+
("signal_mode", "Kalman"),
|
|
46
|
+
("price_shift", 0),
|
|
47
|
+
("point", 0.01),
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
def __init__(self):
|
|
51
|
+
"""Initialize internal state and precompute coefficients."""
|
|
52
|
+
self.addminperiod(2)
|
|
53
|
+
self._velocity = 0.0
|
|
54
|
+
self._sqrt100 = math.sqrt(float(self.p.k) / 100.0) if float(self.p.k) > 0 else 0.0
|
|
55
|
+
self._k100 = float(self.p.k) / 100.0
|
|
56
|
+
self._price_shift = float(self.p.point) * float(self.p.price_shift)
|
|
57
|
+
|
|
58
|
+
def _mode_value(self, mapping, value, default_value):
|
|
59
|
+
if isinstance(value, str):
|
|
60
|
+
return mapping.get(value, default_value)
|
|
61
|
+
return int(value)
|
|
62
|
+
|
|
63
|
+
def _price(self, ago=0):
|
|
64
|
+
mode = self._mode_value(APPLIED_PRICE_MAP, self.p.applied_price, 0)
|
|
65
|
+
open_ = float(self.data.open[ago])
|
|
66
|
+
high = float(self.data.high[ago])
|
|
67
|
+
low = float(self.data.low[ago])
|
|
68
|
+
close = float(self.data.close[ago])
|
|
69
|
+
if mode == 0:
|
|
70
|
+
return close
|
|
71
|
+
if mode == 1:
|
|
72
|
+
return open_
|
|
73
|
+
if mode == 2:
|
|
74
|
+
return high
|
|
75
|
+
if mode == 3:
|
|
76
|
+
return low
|
|
77
|
+
if mode == 4:
|
|
78
|
+
return (high + low) / 2.0
|
|
79
|
+
if mode == 5:
|
|
80
|
+
return (close + high + low) / 3.0
|
|
81
|
+
if mode == 6:
|
|
82
|
+
return (2.0 * close + high + low) / 4.0
|
|
83
|
+
if mode == 8:
|
|
84
|
+
return (open_ + close) / 2.0
|
|
85
|
+
if mode == 9:
|
|
86
|
+
return (open_ + close + high + low) / 4.0
|
|
87
|
+
if mode == 10:
|
|
88
|
+
if close > open_:
|
|
89
|
+
return high
|
|
90
|
+
if close < open_:
|
|
91
|
+
return low
|
|
92
|
+
return close
|
|
93
|
+
if mode == 11:
|
|
94
|
+
if close > open_:
|
|
95
|
+
return (high + close) / 2.0
|
|
96
|
+
if close < open_:
|
|
97
|
+
return (low + close) / 2.0
|
|
98
|
+
return close
|
|
99
|
+
return close
|
|
100
|
+
|
|
101
|
+
def next(self):
|
|
102
|
+
"""Update the filtered value and direction for each bar."""
|
|
103
|
+
price = self._price(0)
|
|
104
|
+
if len(self) == 1:
|
|
105
|
+
self.lines.value[0] = price
|
|
106
|
+
self.lines.color_idx[0] = 0.0
|
|
107
|
+
self._velocity = 0.0
|
|
108
|
+
return
|
|
109
|
+
prev_value = float(self.lines.value[-1])
|
|
110
|
+
distance = price - prev_value
|
|
111
|
+
error = prev_value + distance * self._sqrt100
|
|
112
|
+
self._velocity += distance * self._k100
|
|
113
|
+
value = error + self._velocity + self._price_shift
|
|
114
|
+
self.lines.value[0] = value
|
|
115
|
+
signal_mode = self._mode_value(SIGNAL_MODE_MAP, self.p.signal_mode, 1)
|
|
116
|
+
if signal_mode == 0:
|
|
117
|
+
self.lines.color_idx[0] = 0.0 if prev_value > value else 1.0
|
|
118
|
+
else:
|
|
119
|
+
self.lines.color_idx[0] = 1.0 if self._velocity > 0 else 0.0
|
|
@@ -0,0 +1,127 @@
|
|
|
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
|
+
"KalmanFilterLine",
|
|
14
|
+
"KalmanFilterCandleIndicator",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def weighted_price(data, ago=0):
|
|
19
|
+
"""Return the weighted price ``(high + low + 2*close) / 4`` for a bar.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
data: Data feed exposing high/low/close lines.
|
|
23
|
+
ago: Bar offset (0 is the current bar).
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
The weighted price as a float.
|
|
27
|
+
"""
|
|
28
|
+
return (float(data.high[ago]) + float(data.low[ago]) + 2.0 * float(data.close[ago])) / 4.0
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def indicator_source_price(data, ago=0):
|
|
32
|
+
"""Return the indicator source price for a bar or scalar line.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
data: Data feed with OHLC lines, or a single value line.
|
|
36
|
+
ago: Bar offset (0 is the current bar).
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
The weighted price when OHLC lines are present, otherwise the line's
|
|
40
|
+
value at ``ago``.
|
|
41
|
+
"""
|
|
42
|
+
if all(hasattr(data, attr) for attr in ("high", "low", "close")):
|
|
43
|
+
return weighted_price(data, ago)
|
|
44
|
+
return float(data[ago])
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class KalmanFilterLine(Indicator):
|
|
48
|
+
"""Single-series Kalman-style adaptive filter with a velocity term."""
|
|
49
|
+
|
|
50
|
+
lines = ("value", "color")
|
|
51
|
+
params = (
|
|
52
|
+
("k", 1.0),
|
|
53
|
+
("price_shift_points", 0.0),
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
def __init__(self):
|
|
57
|
+
"""Set the minimum period and initialize filter state."""
|
|
58
|
+
self.addminperiod(2)
|
|
59
|
+
self._initialized = False
|
|
60
|
+
self._velocity = 0.0
|
|
61
|
+
self.sqrt100 = math.sqrt(float(self.p.k) / 100.0)
|
|
62
|
+
self.k100 = float(self.p.k) / 100.0
|
|
63
|
+
|
|
64
|
+
def next(self):
|
|
65
|
+
"""Advance the filter one bar and emit the value and color lines."""
|
|
66
|
+
source_price = indicator_source_price(self.data, 0)
|
|
67
|
+
if not self._initialized:
|
|
68
|
+
self.lines.value[0] = source_price + float(self.p.price_shift_points)
|
|
69
|
+
self.lines.color[0] = 0
|
|
70
|
+
self._velocity = 0.0
|
|
71
|
+
self._initialized = True
|
|
72
|
+
return
|
|
73
|
+
prev_value = float(self.lines.value[-1]) - float(self.p.price_shift_points)
|
|
74
|
+
distance = source_price - prev_value
|
|
75
|
+
error = prev_value + distance * self.sqrt100
|
|
76
|
+
self._velocity += distance * self.k100
|
|
77
|
+
filtered = error + self._velocity + float(self.p.price_shift_points)
|
|
78
|
+
self.lines.value[0] = filtered
|
|
79
|
+
self.lines.color[0] = 1 if self._velocity > 0 else 0
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class KalmanFilterCandleIndicator(Indicator):
|
|
83
|
+
"""Builds Kalman-filtered OHLC candles and a bull/bear color line."""
|
|
84
|
+
|
|
85
|
+
lines = ("k_open", "k_high", "k_low", "k_close", "color")
|
|
86
|
+
params = (
|
|
87
|
+
("k", 1.0),
|
|
88
|
+
("point", 0.01),
|
|
89
|
+
("price_shift", 0),
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
def __init__(self):
|
|
93
|
+
"""Construct per-OHLC Kalman filter lines and set the minimum period."""
|
|
94
|
+
price_shift_points = float(self.p.point) * float(self.p.price_shift)
|
|
95
|
+
self.k_open_line = KalmanFilterLine(
|
|
96
|
+
self.data.open, k=self.p.k, price_shift_points=price_shift_points
|
|
97
|
+
)
|
|
98
|
+
self.k_high_line = KalmanFilterLine(
|
|
99
|
+
self.data.high, k=self.p.k, price_shift_points=price_shift_points
|
|
100
|
+
)
|
|
101
|
+
self.k_low_line = KalmanFilterLine(
|
|
102
|
+
self.data.low, k=self.p.k, price_shift_points=price_shift_points
|
|
103
|
+
)
|
|
104
|
+
self.k_close_line = KalmanFilterLine(
|
|
105
|
+
self.data.close, k=self.p.k, price_shift_points=price_shift_points
|
|
106
|
+
)
|
|
107
|
+
self.addminperiod(3)
|
|
108
|
+
|
|
109
|
+
def next(self):
|
|
110
|
+
"""Assemble the filtered candle and classify its bull/bear color."""
|
|
111
|
+
o = float(self.k_open_line.value[0])
|
|
112
|
+
h = max(float(self.k_high_line.value[0]), o)
|
|
113
|
+
low_price = min(float(self.k_low_line.value[0]), o)
|
|
114
|
+
c = float(self.k_close_line.value[0])
|
|
115
|
+
h = max(h, c)
|
|
116
|
+
low_price = min(low_price, c)
|
|
117
|
+
self.lines.k_open[0] = o
|
|
118
|
+
self.lines.k_high[0] = h
|
|
119
|
+
self.lines.k_low[0] = low_price
|
|
120
|
+
self.lines.k_close[0] = c
|
|
121
|
+
if o < c:
|
|
122
|
+
color = 2
|
|
123
|
+
elif o > c:
|
|
124
|
+
color = 0
|
|
125
|
+
else:
|
|
126
|
+
color = 1
|
|
127
|
+
self.lines.color[0] = color
|
|
@@ -0,0 +1,150 @@
|
|
|
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 (
|
|
11
|
+
ExponentialMovingAverage,
|
|
12
|
+
Indicator,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"KAMAIndicator",
|
|
17
|
+
"ColorMomentumAMAIndicator",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def resolve_price_line(data, mode):
|
|
22
|
+
"""Return the price line selected by an MT5 applied-price mode.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
data: The data feed providing OHLC lines.
|
|
26
|
+
mode: Applied-price mode name (e.g. ``price_close``, ``price_median``).
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
The line or line expression for the requested applied price; defaults
|
|
30
|
+
to the close line for unrecognized modes.
|
|
31
|
+
"""
|
|
32
|
+
price_mode = str(mode).lower()
|
|
33
|
+
if price_mode in {"price_open", "open"}:
|
|
34
|
+
return data.open
|
|
35
|
+
if price_mode in {"price_high", "high"}:
|
|
36
|
+
return data.high
|
|
37
|
+
if price_mode in {"price_low", "low"}:
|
|
38
|
+
return data.low
|
|
39
|
+
if price_mode in {"price_median", "median"}:
|
|
40
|
+
return (data.high + data.low) / 2.0
|
|
41
|
+
if price_mode in {"price_typical", "typical"}:
|
|
42
|
+
return (data.high + data.low + data.close) / 3.0
|
|
43
|
+
if price_mode in {"price_weighted", "weighted"}:
|
|
44
|
+
return (data.high + data.low + data.close + data.close) / 4.0
|
|
45
|
+
if price_mode in {"price_simpl", "simpl"}:
|
|
46
|
+
return (data.open + data.close) / 2.0
|
|
47
|
+
if price_mode in {"price_quarter", "quarter"}:
|
|
48
|
+
return (data.high + data.low + data.open + data.close) / 4.0
|
|
49
|
+
return data.close
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class KAMAIndicator(Indicator):
|
|
53
|
+
"""Kaufman Adaptive Moving Average with both event and vectorized modes."""
|
|
54
|
+
|
|
55
|
+
lines = ("ama",)
|
|
56
|
+
params = (
|
|
57
|
+
("period", 9),
|
|
58
|
+
("fast_period", 2),
|
|
59
|
+
("slow_period", 30),
|
|
60
|
+
("power", 2.0),
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
def __init__(self):
|
|
64
|
+
"""Set the minimum period required before emitting values."""
|
|
65
|
+
self.addminperiod(max(self.p.period, self.p.slow_period) + 2)
|
|
66
|
+
|
|
67
|
+
def next(self):
|
|
68
|
+
"""Compute the adaptive moving average for the current bar."""
|
|
69
|
+
period = int(self.p.period)
|
|
70
|
+
current = float(self.data[0])
|
|
71
|
+
prev = float(self.lines.ama[-1]) if len(self) > 0 else current
|
|
72
|
+
if not math.isfinite(prev):
|
|
73
|
+
prev = 0.0
|
|
74
|
+
if not math.isfinite(current):
|
|
75
|
+
self.lines.ama[0] = prev
|
|
76
|
+
return
|
|
77
|
+
if len(self.data) <= period:
|
|
78
|
+
self.lines.ama[0] = current
|
|
79
|
+
return
|
|
80
|
+
change = abs(float(self.data[0]) - float(self.data[-period]))
|
|
81
|
+
volatility = 0.0
|
|
82
|
+
for i in range(period):
|
|
83
|
+
left = float(self.data[-i])
|
|
84
|
+
right = float(self.data[-i - 1])
|
|
85
|
+
if math.isfinite(left) and math.isfinite(right):
|
|
86
|
+
volatility += abs(left - right)
|
|
87
|
+
er = (change / volatility) if volatility else 0.0
|
|
88
|
+
fast_sc = 2.0 / (int(self.p.fast_period) + 1.0)
|
|
89
|
+
slow_sc = 2.0 / (int(self.p.slow_period) + 1.0)
|
|
90
|
+
sc = (er * (fast_sc - slow_sc) + slow_sc) ** float(self.p.power)
|
|
91
|
+
self.lines.ama[0] = prev + sc * (current - prev)
|
|
92
|
+
|
|
93
|
+
def once(self, start, end):
|
|
94
|
+
"""Vectorized KAMA computation over the array index range.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
start: Start index (inclusive) of the range to compute.
|
|
98
|
+
end: End index (exclusive) of the range to compute.
|
|
99
|
+
"""
|
|
100
|
+
period = int(self.p.period)
|
|
101
|
+
src = self.data.array
|
|
102
|
+
dst = self.lines.ama.array
|
|
103
|
+
fast_sc = 2.0 / (int(self.p.fast_period) + 1.0)
|
|
104
|
+
slow_sc = 2.0 / (int(self.p.slow_period) + 1.0)
|
|
105
|
+
power = float(self.p.power)
|
|
106
|
+
for i in range(start, end):
|
|
107
|
+
current = float(src[i])
|
|
108
|
+
prev = float(dst[i - 1]) if i > 0 else current
|
|
109
|
+
if not math.isfinite(prev):
|
|
110
|
+
prev = 0.0
|
|
111
|
+
if not math.isfinite(current):
|
|
112
|
+
dst[i] = prev
|
|
113
|
+
continue
|
|
114
|
+
if i <= period:
|
|
115
|
+
dst[i] = current
|
|
116
|
+
continue
|
|
117
|
+
change = abs(current - float(src[i - period]))
|
|
118
|
+
volatility = 0.0
|
|
119
|
+
for j in range(period):
|
|
120
|
+
left = float(src[i - j])
|
|
121
|
+
right = float(src[i - j - 1])
|
|
122
|
+
if math.isfinite(left) and math.isfinite(right):
|
|
123
|
+
volatility += abs(left - right)
|
|
124
|
+
er = (change / volatility) if volatility else 0.0
|
|
125
|
+
sc = (er * (fast_sc - slow_sc) + slow_sc) ** power
|
|
126
|
+
dst[i] = prev + sc * (current - prev)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class ColorMomentumAMAIndicator(Indicator):
|
|
130
|
+
"""EMA-smoothed momentum line used by the ColorMomentum_AMA strategy."""
|
|
131
|
+
|
|
132
|
+
lines = ("value",)
|
|
133
|
+
params = (
|
|
134
|
+
("alength", 8),
|
|
135
|
+
("ama_period", 9),
|
|
136
|
+
("fast_ma_period", 2),
|
|
137
|
+
("slow_ma_period", 30),
|
|
138
|
+
("ipc", "price_close"),
|
|
139
|
+
("g", 2.0),
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
def __init__(self):
|
|
143
|
+
"""Build the EMA-smoothed momentum line and set the minimum period."""
|
|
144
|
+
price_line = resolve_price_line(self.data, self.p.ipc)
|
|
145
|
+
momentum = price_line - price_line(-int(self.p.alength))
|
|
146
|
+
self.lines.value = ExponentialMovingAverage(
|
|
147
|
+
momentum,
|
|
148
|
+
period=max(1, int(self.p.ama_period)),
|
|
149
|
+
)
|
|
150
|
+
self.addminperiod(int(self.p.alength) + int(self.p.ama_period) + 5)
|
|
@@ -0,0 +1,99 @@
|
|
|
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
|
+
"KaracaticaIndicator",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class KaracaticaIndicator(Indicator):
|
|
16
|
+
"""Reconstructs Karacatica from MQ5 source.
|
|
17
|
+
|
|
18
|
+
Uses ATR(iPeriod), ADX(iPeriod) +DI/-DI, and close-vs-close(iPeriod-ago)
|
|
19
|
+
to generate buy/sell arrows with direction latch to avoid repeats.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
lines = ("buy_arrow", "sell_arrow")
|
|
23
|
+
params = (("iperiod", 70),)
|
|
24
|
+
|
|
25
|
+
def __init__(self):
|
|
26
|
+
"""Initialize the ATR scaling factor, direction latch, and min period."""
|
|
27
|
+
self._s = 1.5 / 2.0
|
|
28
|
+
self._ltr = 0 # 0=none, 1=last was buy, 2=last was sell
|
|
29
|
+
self.addminperiod(int(self.p.iperiod) + 2)
|
|
30
|
+
|
|
31
|
+
def _calc_atr(self):
|
|
32
|
+
period = int(self.p.iperiod)
|
|
33
|
+
total = 0.0
|
|
34
|
+
for i in range(period):
|
|
35
|
+
hi = float(self.data.high[-i])
|
|
36
|
+
lo = float(self.data.low[-i])
|
|
37
|
+
prev_c = float(self.data.close[-(i + 1)])
|
|
38
|
+
total += max(hi - lo, abs(hi - prev_c), abs(prev_c - lo))
|
|
39
|
+
return total / period
|
|
40
|
+
|
|
41
|
+
def _calc_adx_di(self):
|
|
42
|
+
period = int(self.p.iperiod)
|
|
43
|
+
plus_dm_sum = 0.0
|
|
44
|
+
minus_dm_sum = 0.0
|
|
45
|
+
tr_sum = 0.0
|
|
46
|
+
for i in range(period):
|
|
47
|
+
hi = float(self.data.high[-i])
|
|
48
|
+
lo = float(self.data.low[-i])
|
|
49
|
+
prev_hi = float(self.data.high[-(i + 1)])
|
|
50
|
+
prev_lo = float(self.data.low[-(i + 1)])
|
|
51
|
+
prev_c = float(self.data.close[-(i + 1)])
|
|
52
|
+
up_move = hi - prev_hi
|
|
53
|
+
down_move = prev_lo - lo
|
|
54
|
+
plus_dm = up_move if (up_move > down_move and up_move > 0) else 0.0
|
|
55
|
+
minus_dm = down_move if (down_move > up_move and down_move > 0) else 0.0
|
|
56
|
+
tr = max(hi - lo, abs(hi - prev_c), abs(prev_c - lo))
|
|
57
|
+
plus_dm_sum += plus_dm
|
|
58
|
+
minus_dm_sum += minus_dm
|
|
59
|
+
tr_sum += tr
|
|
60
|
+
if tr_sum == 0:
|
|
61
|
+
return 0.0, 0.0
|
|
62
|
+
plus_di = 100.0 * plus_dm_sum / tr_sum
|
|
63
|
+
minus_di = 100.0 * minus_dm_sum / tr_sum
|
|
64
|
+
return plus_di, minus_di
|
|
65
|
+
|
|
66
|
+
def next(self):
|
|
67
|
+
"""Emit ATR-offset buy/sell arrows on latched directional breakouts.
|
|
68
|
+
|
|
69
|
+
Computes ATR and +DI/-DI over ``iperiod`` and, when the close exceeds
|
|
70
|
+
its value ``iperiod`` bars ago with +DI dominant (and the last arrow was
|
|
71
|
+
not a buy), places a buy arrow below the low; the symmetric condition
|
|
72
|
+
places a sell arrow above the high. The direction latch prevents
|
|
73
|
+
consecutive arrows of the same side.
|
|
74
|
+
"""
|
|
75
|
+
period = int(self.p.iperiod)
|
|
76
|
+
if len(self.data) < period + 2:
|
|
77
|
+
self.lines.buy_arrow[0] = 0.0
|
|
78
|
+
self.lines.sell_arrow[0] = 0.0
|
|
79
|
+
return
|
|
80
|
+
|
|
81
|
+
atr = self._calc_atr()
|
|
82
|
+
plus_di, minus_di = self._calc_adx_di()
|
|
83
|
+
cur_close = float(self.data.close[0])
|
|
84
|
+
past_close = float(self.data.close[-period])
|
|
85
|
+
cur_high = float(self.data.high[0])
|
|
86
|
+
cur_low = float(self.data.low[0])
|
|
87
|
+
|
|
88
|
+
buy_val = 0.0
|
|
89
|
+
sell_val = 0.0
|
|
90
|
+
|
|
91
|
+
if cur_close > past_close and plus_di > minus_di and self._ltr != 1:
|
|
92
|
+
buy_val = cur_low - atr * self._s
|
|
93
|
+
self._ltr = 1
|
|
94
|
+
if cur_close < past_close and plus_di < minus_di and self._ltr != 2:
|
|
95
|
+
sell_val = cur_high + atr * self._s
|
|
96
|
+
self._ltr = 2
|
|
97
|
+
|
|
98
|
+
self.lines.buy_arrow[0] = buy_val
|
|
99
|
+
self.lines.sell_arrow[0] = sell_val
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Functional-test indicators migrated to contrib.
|
|
3
|
+
|
|
4
|
+
Generated from a single functional strategy module to preserve file-local
|
|
5
|
+
helper functions and constants without cross-test name collisions.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .. import Indicator
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"KDJIndicator",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class KDJIndicator(Indicator):
|
|
16
|
+
"""Indicator class implementing the custom KDJ oscillator.
|
|
17
|
+
|
|
18
|
+
Lines:
|
|
19
|
+
kdc (Line): Output difference line (%K - %D).
|
|
20
|
+
rsv (Line): Raw Stochastic Value line.
|
|
21
|
+
k (Line): Smoothed %K line.
|
|
22
|
+
d (Line): Smoothed %D line.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
lines = ("kdc", "rsv", "k", "d")
|
|
26
|
+
params = (
|
|
27
|
+
("m1", 3),
|
|
28
|
+
("m2", 6),
|
|
29
|
+
("kdj_period", 30),
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
def __init__(self):
|
|
33
|
+
"""Initialize the custom KDJ indicator and establish minimum warmup period."""
|
|
34
|
+
self.addminperiod(int(self.p.kdj_period) + int(self.p.m2) + 2)
|
|
35
|
+
|
|
36
|
+
def next(self):
|
|
37
|
+
"""Calculate RSV, %K, %D, and %K-%D values on each new bar."""
|
|
38
|
+
kdj_period = int(self.p.kdj_period)
|
|
39
|
+
m1 = int(self.p.m1)
|
|
40
|
+
m2 = int(self.p.m2)
|
|
41
|
+
highs = [float(self.data.high[-i]) for i in range(kdj_period)]
|
|
42
|
+
lows = [float(self.data.low[-i]) for i in range(kdj_period)]
|
|
43
|
+
max_high = max(highs)
|
|
44
|
+
min_low = min(lows)
|
|
45
|
+
if max_high - min_low != 0.0:
|
|
46
|
+
self.lines.rsv[0] = (float(self.data.close[0]) - min_low) / (max_high - min_low) * 100.0
|
|
47
|
+
else:
|
|
48
|
+
self.lines.rsv[0] = 1.0
|
|
49
|
+
rsv_values = []
|
|
50
|
+
for i in range(m1):
|
|
51
|
+
value = float(self.lines.rsv[-i]) if len(self) > i else 50.0
|
|
52
|
+
rsv_values.append(value)
|
|
53
|
+
self.lines.k[0] = sum(rsv_values) / float(m1)
|
|
54
|
+
k_values = []
|
|
55
|
+
for i in range(m2):
|
|
56
|
+
value = float(self.lines.k[-i]) if len(self) > i else 50.0
|
|
57
|
+
k_values.append(value)
|
|
58
|
+
self.lines.d[0] = sum(k_values) / float(m2)
|
|
59
|
+
self.lines.kdc[0] = float(self.lines.k[0]) - float(self.lines.d[0])
|