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,80 @@
|
|
|
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
|
+
RSI,
|
|
12
|
+
Indicator,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"EmaRsiVa",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class EmaRsiVa(Indicator):
|
|
21
|
+
"""Volatility-adaptive EMA whose smoothing reacts to RSI distance from 50."""
|
|
22
|
+
|
|
23
|
+
lines = ("value",)
|
|
24
|
+
params = (
|
|
25
|
+
("rsi_period", 14),
|
|
26
|
+
("ema_periods", 14.0),
|
|
27
|
+
("applied_price", "close"),
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
def __init__(self):
|
|
31
|
+
"""Resolve the applied price line, build RSI, and set warmup period."""
|
|
32
|
+
self.price_line = self._resolve_price_line()
|
|
33
|
+
self.rsi = RSI(self.price_line, period=self.p.rsi_period)
|
|
34
|
+
self.addminperiod(max(2, int(self.p.rsi_period) * 2))
|
|
35
|
+
|
|
36
|
+
def _resolve_price_line(self):
|
|
37
|
+
ap = str(self.p.applied_price).lower()
|
|
38
|
+
if ap in ("close", "price_close"):
|
|
39
|
+
return self.data.close
|
|
40
|
+
if ap in ("open", "price_open"):
|
|
41
|
+
return self.data.open
|
|
42
|
+
if ap in ("high", "price_high"):
|
|
43
|
+
return self.data.high
|
|
44
|
+
if ap in ("low", "price_low"):
|
|
45
|
+
return self.data.low
|
|
46
|
+
if ap in ("median", "price_median"):
|
|
47
|
+
return (self.data.high + self.data.low) / 2.0
|
|
48
|
+
if ap in ("typical", "price_typical"):
|
|
49
|
+
return (self.data.high + self.data.low + self.data.close) / 3.0
|
|
50
|
+
if ap in ("weighted", "price_weighted"):
|
|
51
|
+
return (self.data.high + self.data.low + self.data.close * 2.0) / 4.0
|
|
52
|
+
return self.data.close
|
|
53
|
+
|
|
54
|
+
def next(self):
|
|
55
|
+
"""Update the adaptive EMA line using the RSI-modulated smoothing factor."""
|
|
56
|
+
price = float(self.price_line[0])
|
|
57
|
+
if len(self) == int(self.p.rsi_period) * 2:
|
|
58
|
+
self.lines.value[0] = price
|
|
59
|
+
return
|
|
60
|
+
|
|
61
|
+
rsi_value = float(self.rsi[0]) if len(self.rsi) else float("nan")
|
|
62
|
+
if not math.isfinite(rsi_value):
|
|
63
|
+
prev = (
|
|
64
|
+
float(self.lines.value[-1]) if math.isfinite(float(self.lines.value[-1])) else price
|
|
65
|
+
)
|
|
66
|
+
self.lines.value[0] = prev
|
|
67
|
+
return
|
|
68
|
+
|
|
69
|
+
rsvoltl = abs(rsi_value - 50.0) + 1.0
|
|
70
|
+
multi = (5.0 + 100.0 / float(self.p.rsi_period)) / (
|
|
71
|
+
0.06 + 0.92 * rsvoltl + 0.02 * rsvoltl**2
|
|
72
|
+
)
|
|
73
|
+
pdsx = max(1.0, multi * float(self.p.ema_periods))
|
|
74
|
+
alpha = 2.0 / (pdsx + 1.0)
|
|
75
|
+
|
|
76
|
+
prev_value = float(self.lines.value[-1])
|
|
77
|
+
if not math.isfinite(prev_value):
|
|
78
|
+
prev_value = float(self.price_line[-1])
|
|
79
|
+
|
|
80
|
+
self.lines.value[0] = price * alpha + prev_value * (1.0 - alpha)
|
|
@@ -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
|
+
"EnvelopesJpAlonso",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class EnvelopesJpAlonso(Indicator):
|
|
19
|
+
"""Compute static upper/lower envelope bands around a simple moving average."""
|
|
20
|
+
|
|
21
|
+
lines = ("mid", "upper", "lower")
|
|
22
|
+
params = (
|
|
23
|
+
("period", 200),
|
|
24
|
+
("deviation", 0.35),
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
def __init__(self):
|
|
28
|
+
"""Initialize envelope lines from the configured SMA period and deviation."""
|
|
29
|
+
self.lines.mid = SimpleMovingAverage(self.data.close, period=self.p.period)
|
|
30
|
+
ratio = float(self.p.deviation) / 100.0
|
|
31
|
+
self.lines.upper = self.lines.mid * (1.0 + ratio)
|
|
32
|
+
self.lines.lower = self.lines.mid * (1.0 - ratio)
|
|
@@ -0,0 +1,120 @@
|
|
|
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
|
+
"F2aAOIndicator",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class F2aAOIndicator(Indicator):
|
|
21
|
+
"""F2a_AO arrow indicator from a fast/slow/filter EMA system.
|
|
22
|
+
|
|
23
|
+
Builds fast, slow and filter EMAs of a weighted price and emits a ``buy``
|
|
24
|
+
arrow below the bar when the fast-minus-slow spread turns up with filter
|
|
25
|
+
confirmation, or a ``sell`` arrow above the bar on the bearish turn, using an
|
|
26
|
+
internal latch so arrows alternate direction.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
lines = ("sell", "buy")
|
|
30
|
+
params = (
|
|
31
|
+
("ma_filtr", 3),
|
|
32
|
+
("ma_fast", 13),
|
|
33
|
+
("ma_slow", 144),
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
def __init__(self):
|
|
37
|
+
"""Build the fast/slow/filter EMAs and set the minimum period."""
|
|
38
|
+
series = (
|
|
39
|
+
self.data.close * 5.0 + self.data.open * 2.0 + self.data.high + self.data.low
|
|
40
|
+
) / 9.0
|
|
41
|
+
self._fast = ExponentialMovingAverage(series, period=max(1, int(self.p.ma_fast)))
|
|
42
|
+
self._slow = ExponentialMovingAverage(series, period=max(1, int(self.p.ma_slow)))
|
|
43
|
+
self._filter = ExponentialMovingAverage(series, period=max(1, int(self.p.ma_filtr)))
|
|
44
|
+
self.addminperiod(max(int(self.p.ma_slow), int(self.p.ma_fast), int(self.p.ma_filtr)) + 20)
|
|
45
|
+
self._trend = 0
|
|
46
|
+
|
|
47
|
+
def next(self):
|
|
48
|
+
"""Compute buy/sell arrows for the current bar (event-driven mode).
|
|
49
|
+
|
|
50
|
+
Detects a confirmed turn in the fast-minus-slow spread and plots a buy
|
|
51
|
+
arrow below the low or a sell arrow above the high, offset by half the
|
|
52
|
+
recent average range, toggling the internal trend latch.
|
|
53
|
+
"""
|
|
54
|
+
value1_0 = float(self._fast[0]) - float(self._slow[0])
|
|
55
|
+
value1_1 = float(self._fast[-1]) - float(self._slow[-1])
|
|
56
|
+
value1_2 = float(self._fast[-2]) - float(self._slow[-2])
|
|
57
|
+
current = float(self._filter[0])
|
|
58
|
+
prev = float(self._filter[-1])
|
|
59
|
+
avg_range = 0.0
|
|
60
|
+
for count in range(10):
|
|
61
|
+
avg_range += abs(float(self.data.high[-count]) - float(self.data.low[-count]))
|
|
62
|
+
range_value = avg_range / 10.0
|
|
63
|
+
self.lines.buy[0] = 0.0
|
|
64
|
+
self.lines.sell[0] = 0.0
|
|
65
|
+
if self._trend <= 0:
|
|
66
|
+
if value1_0 > value1_1 and current >= prev and value1_1 <= value1_2:
|
|
67
|
+
self.lines.buy[0] = float(self.data.low[0]) - range_value * 0.5
|
|
68
|
+
self._trend = 1
|
|
69
|
+
if self._trend >= 0:
|
|
70
|
+
if value1_0 < value1_1 and current <= prev and value1_1 >= value1_2:
|
|
71
|
+
self.lines.sell[0] = float(self.data.high[0]) + range_value * 0.5
|
|
72
|
+
self._trend = -1
|
|
73
|
+
|
|
74
|
+
def once(self, start, end):
|
|
75
|
+
"""Compute buy/sell arrows over a range of bars (vectorized mode).
|
|
76
|
+
|
|
77
|
+
Vectorized equivalent of ``next`` used under ``runonce``: iterates the
|
|
78
|
+
arrays from ``start`` to ``end``, detecting confirmed spread turns and
|
|
79
|
+
writing buy/sell arrow values while maintaining the trend latch.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
start: First bar index to process.
|
|
83
|
+
end: Stop index (exclusive) for processing.
|
|
84
|
+
"""
|
|
85
|
+
fast = self._fast.array
|
|
86
|
+
slow = self._slow.array
|
|
87
|
+
filtr = self._filter.array
|
|
88
|
+
high = self.data.high.array
|
|
89
|
+
low = self.data.low.array
|
|
90
|
+
buy = self.lines.buy.array
|
|
91
|
+
sell = self.lines.sell.array
|
|
92
|
+
trend = 0
|
|
93
|
+
for i in range(start, end):
|
|
94
|
+
buy[i] = 0.0
|
|
95
|
+
sell[i] = 0.0
|
|
96
|
+
if i < 12:
|
|
97
|
+
continue
|
|
98
|
+
value1_0 = float(fast[i]) - float(slow[i])
|
|
99
|
+
value1_1 = float(fast[i - 1]) - float(slow[i - 1])
|
|
100
|
+
value1_2 = float(fast[i - 2]) - float(slow[i - 2])
|
|
101
|
+
current = float(filtr[i])
|
|
102
|
+
prev = float(filtr[i - 1])
|
|
103
|
+
if not all(math.isfinite(v) for v in (value1_0, value1_1, value1_2, current, prev)):
|
|
104
|
+
continue
|
|
105
|
+
avg_range = 0.0
|
|
106
|
+
valid_ranges = 0
|
|
107
|
+
for count in range(10):
|
|
108
|
+
idx = i - count
|
|
109
|
+
bar_range = abs(float(high[idx]) - float(low[idx]))
|
|
110
|
+
if math.isfinite(bar_range):
|
|
111
|
+
avg_range += bar_range
|
|
112
|
+
valid_ranges += 1
|
|
113
|
+
range_value = avg_range / valid_ranges if valid_ranges else 0.0
|
|
114
|
+
if trend <= 0 and value1_0 > value1_1 and current >= prev and value1_1 <= value1_2:
|
|
115
|
+
buy[i] = float(low[i]) - range_value * 0.5
|
|
116
|
+
trend = 1
|
|
117
|
+
if trend >= 0 and value1_0 < value1_1 and current <= prev and value1_1 >= value1_2:
|
|
118
|
+
sell[i] = float(high[i]) + range_value * 0.5
|
|
119
|
+
trend = -1
|
|
120
|
+
self._trend = trend
|
|
@@ -0,0 +1,179 @@
|
|
|
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
|
+
"FatlFilter",
|
|
14
|
+
"JFatlApprox",
|
|
15
|
+
"JFatlCandleApprox",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class FatlFilter(Indicator):
|
|
20
|
+
"""Finite impulse response filter approximation used by JFatl indicators."""
|
|
21
|
+
|
|
22
|
+
lines = ("fatl",)
|
|
23
|
+
coeffs = (
|
|
24
|
+
0.4360409450,
|
|
25
|
+
0.3658689069,
|
|
26
|
+
0.2460452079,
|
|
27
|
+
0.1104506886,
|
|
28
|
+
-0.0054034585,
|
|
29
|
+
-0.0760367731,
|
|
30
|
+
-0.0933058722,
|
|
31
|
+
-0.0670110374,
|
|
32
|
+
-0.0190795053,
|
|
33
|
+
0.0259609206,
|
|
34
|
+
0.0502044896,
|
|
35
|
+
0.0477818607,
|
|
36
|
+
0.0249252327,
|
|
37
|
+
-0.0047706151,
|
|
38
|
+
-0.0272432537,
|
|
39
|
+
-0.0338917071,
|
|
40
|
+
-0.0244141482,
|
|
41
|
+
-0.0055774838,
|
|
42
|
+
0.0128149838,
|
|
43
|
+
0.0226522218,
|
|
44
|
+
0.0208778257,
|
|
45
|
+
0.0100299086,
|
|
46
|
+
-0.0036771622,
|
|
47
|
+
-0.0136744850,
|
|
48
|
+
-0.0160483392,
|
|
49
|
+
-0.0108597376,
|
|
50
|
+
-0.0016060704,
|
|
51
|
+
0.0069480557,
|
|
52
|
+
0.0110573605,
|
|
53
|
+
0.0095711419,
|
|
54
|
+
0.0040444064,
|
|
55
|
+
-0.0023824623,
|
|
56
|
+
-0.0067093714,
|
|
57
|
+
-0.0072003400,
|
|
58
|
+
-0.0047717710,
|
|
59
|
+
0.0005541115,
|
|
60
|
+
0.0007860160,
|
|
61
|
+
0.0130129076,
|
|
62
|
+
0.0040364019,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
def __init__(self):
|
|
66
|
+
"""Initialize the indicator with its required minimum period."""
|
|
67
|
+
self.addminperiod(len(self.coeffs))
|
|
68
|
+
|
|
69
|
+
def next(self):
|
|
70
|
+
"""Compute the FIR-style filtered value for the active bar."""
|
|
71
|
+
total = 0.0
|
|
72
|
+
for idx, coef in enumerate(self.coeffs):
|
|
73
|
+
total += coef * float(self.data[-idx])
|
|
74
|
+
self.lines.fatl[0] = total
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class JFatlApprox(Indicator):
|
|
78
|
+
"""Double-smoothed approximation indicator built from JFatl coefficients."""
|
|
79
|
+
|
|
80
|
+
lines = ("jfatl",)
|
|
81
|
+
params = (
|
|
82
|
+
("length", 5),
|
|
83
|
+
("phase", 100),
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
def __init__(self):
|
|
87
|
+
"""Initialize smoothing state, limits, and minimum period."""
|
|
88
|
+
self._length = max(2, int(self.p.length))
|
|
89
|
+
self._phase = max(-100, min(100, int(self.p.phase)))
|
|
90
|
+
self._coeffs = FatlFilter.coeffs
|
|
91
|
+
base_alpha = 2.0 / (self._length + 1.0)
|
|
92
|
+
self._alpha = max(0.01, min(0.95, base_alpha * (1.0 + self._phase / 200.0)))
|
|
93
|
+
self._phase_gain = self._phase / 200.0
|
|
94
|
+
self._ema1 = None
|
|
95
|
+
self._ema2 = None
|
|
96
|
+
self.addminperiod(len(self._coeffs))
|
|
97
|
+
|
|
98
|
+
def next(self):
|
|
99
|
+
"""Update smoothed output from incoming raw weighted observations."""
|
|
100
|
+
raw = 0.0
|
|
101
|
+
for idx, coef in enumerate(self._coeffs):
|
|
102
|
+
raw += coef * float(self.data[-idx])
|
|
103
|
+
if self._ema1 is None:
|
|
104
|
+
self._ema1 = raw
|
|
105
|
+
self._ema2 = raw
|
|
106
|
+
else:
|
|
107
|
+
self._ema1 = self._ema1 + self._alpha * (raw - self._ema1)
|
|
108
|
+
self._ema2 = self._ema2 + self._alpha * (self._ema1 - self._ema2)
|
|
109
|
+
self.lines.jfatl[0] = self._ema1 + self._phase_gain * (self._ema1 - self._ema2)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class JFatlCandleApprox(Indicator):
|
|
113
|
+
"""Reconstruct candle-like open/high/low/close and color state from JFatl."""
|
|
114
|
+
|
|
115
|
+
lines = ("open_value", "high_value", "low_value", "close_value", "color_state")
|
|
116
|
+
params = (
|
|
117
|
+
("length", 5),
|
|
118
|
+
("phase", 100),
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
def __init__(self):
|
|
122
|
+
"""Initialize per-field smoothing states and min-period requirements."""
|
|
123
|
+
self._coeffs = FatlFilter.coeffs
|
|
124
|
+
self._length = max(2, int(self.p.length))
|
|
125
|
+
self._phase = max(-100, min(100, int(self.p.phase)))
|
|
126
|
+
base_alpha = 2.0 / (self._length + 1.0)
|
|
127
|
+
self._alpha = max(0.01, min(0.95, base_alpha * (1.0 + self._phase / 200.0)))
|
|
128
|
+
self._phase_gain = self._phase / 200.0
|
|
129
|
+
self._states = {
|
|
130
|
+
"open": {"ema1": None, "ema2": None},
|
|
131
|
+
"high": {"ema1": None, "ema2": None},
|
|
132
|
+
"low": {"ema1": None, "ema2": None},
|
|
133
|
+
"close": {"ema1": None, "ema2": None},
|
|
134
|
+
}
|
|
135
|
+
self.addminperiod(len(self._coeffs))
|
|
136
|
+
|
|
137
|
+
@staticmethod
|
|
138
|
+
def _finite(value):
|
|
139
|
+
return value is not None and math.isfinite(value)
|
|
140
|
+
|
|
141
|
+
def _raw_fatl(self, line):
|
|
142
|
+
total = 0.0
|
|
143
|
+
for idx, coef in enumerate(self._coeffs):
|
|
144
|
+
total += coef * float(line[-idx])
|
|
145
|
+
return total
|
|
146
|
+
|
|
147
|
+
def _smooth(self, key, raw):
|
|
148
|
+
state = self._states[key]
|
|
149
|
+
if state["ema1"] is None:
|
|
150
|
+
state["ema1"] = raw
|
|
151
|
+
state["ema2"] = raw
|
|
152
|
+
else:
|
|
153
|
+
state["ema1"] = state["ema1"] + self._alpha * (raw - state["ema1"])
|
|
154
|
+
state["ema2"] = state["ema2"] + self._alpha * (state["ema1"] - state["ema2"])
|
|
155
|
+
return state["ema1"] + self._phase_gain * (state["ema1"] - state["ema2"])
|
|
156
|
+
|
|
157
|
+
def next(self):
|
|
158
|
+
"""Generate smoothed OHLC and direction color values for the current bar."""
|
|
159
|
+
open_value = self._smooth("open", self._raw_fatl(self.data.open))
|
|
160
|
+
high_value = self._smooth("high", self._raw_fatl(self.data.high))
|
|
161
|
+
low_value = self._smooth("low", self._raw_fatl(self.data.low))
|
|
162
|
+
close_value = self._smooth("close", self._raw_fatl(self.data.close))
|
|
163
|
+
if not all(self._finite(v) for v in (open_value, high_value, low_value, close_value)):
|
|
164
|
+
self.lines.open_value[0] = float("nan")
|
|
165
|
+
self.lines.high_value[0] = float("nan")
|
|
166
|
+
self.lines.low_value[0] = float("nan")
|
|
167
|
+
self.lines.close_value[0] = float("nan")
|
|
168
|
+
self.lines.color_state[0] = float("nan")
|
|
169
|
+
return
|
|
170
|
+
max_value = max(open_value, close_value)
|
|
171
|
+
min_value = min(open_value, close_value)
|
|
172
|
+
high_value = max(max_value, high_value)
|
|
173
|
+
low_value = min(min_value, low_value)
|
|
174
|
+
color_state = 2.0 if open_value < close_value else 0.0 if open_value > close_value else 1.0
|
|
175
|
+
self.lines.open_value[0] = open_value
|
|
176
|
+
self.lines.high_value[0] = high_value
|
|
177
|
+
self.lines.low_value[0] = low_value
|
|
178
|
+
self.lines.close_value[0] = close_value
|
|
179
|
+
self.lines.color_state[0] = color_state
|
|
@@ -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
|
+
"FiboCandlesIndicator",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
FIBO_LEVELS = {1: 0.236, 2: 0.382, 3: 0.500, 4: 0.618, 5: 0.762}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class FiboCandlesIndicator(Indicator):
|
|
19
|
+
"""Reconstructs the FiboCandles indicator from MQ5 source.
|
|
20
|
+
|
|
21
|
+
Uses period-bar high/low range * fibo level to detect trend flips.
|
|
22
|
+
color line: 0 = bullish (trend +1), 1 = bearish (trend -1).
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
lines = ("color",)
|
|
26
|
+
params = (
|
|
27
|
+
("period", 10),
|
|
28
|
+
("fibo_level", 1),
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
def __init__(self):
|
|
32
|
+
"""Initialize indicator variables, selected fibonacci ratio level, and trend state."""
|
|
33
|
+
self._level = FIBO_LEVELS.get(int(self.p.fibo_level), 0.236)
|
|
34
|
+
self._trend = 1
|
|
35
|
+
self.addminperiod(int(self.p.period) + 1)
|
|
36
|
+
|
|
37
|
+
def next(self):
|
|
38
|
+
"""Determine trend direction and assign bullish/bearish candle colors."""
|
|
39
|
+
period = int(self.p.period)
|
|
40
|
+
level = self._level
|
|
41
|
+
|
|
42
|
+
# maxHigh / minLow over [bar, bar+period) in MQ5 (as-series)
|
|
43
|
+
# In backtrader forward indexing: last `period` bars including current
|
|
44
|
+
max_high = max(float(self.data.high[-i]) for i in range(period))
|
|
45
|
+
min_low = min(float(self.data.low[-i]) for i in range(period))
|
|
46
|
+
rng = max_high - min_low
|
|
47
|
+
|
|
48
|
+
o = float(self.data.open[0])
|
|
49
|
+
c = float(self.data.close[0])
|
|
50
|
+
float(self.data.high[0])
|
|
51
|
+
float(self.data.low[0])
|
|
52
|
+
trend = self._trend
|
|
53
|
+
|
|
54
|
+
if o > c: # bearish candle
|
|
55
|
+
if not (trend < 0 and rng * level < c - min_low):
|
|
56
|
+
trend = 1
|
|
57
|
+
else:
|
|
58
|
+
trend = -1
|
|
59
|
+
else: # bullish candle
|
|
60
|
+
if not (trend > 0 and rng * level < max_high - c):
|
|
61
|
+
trend = -1
|
|
62
|
+
else:
|
|
63
|
+
trend = 1
|
|
64
|
+
|
|
65
|
+
# Color assignment
|
|
66
|
+
if trend == 1:
|
|
67
|
+
open_buf = max(o, c)
|
|
68
|
+
close_buf = min(o, c)
|
|
69
|
+
else:
|
|
70
|
+
open_buf = min(o, c)
|
|
71
|
+
close_buf = max(o, c)
|
|
72
|
+
|
|
73
|
+
if open_buf > close_buf:
|
|
74
|
+
self.lines.color[0] = 1.0 # bearish color
|
|
75
|
+
else:
|
|
76
|
+
self.lines.color[0] = 0.0 # bullish color
|
|
77
|
+
|
|
78
|
+
self._trend = trend
|
|
@@ -0,0 +1,100 @@
|
|
|
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
|
+
"FineTuningMA",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _price_value(data, shift, mode):
|
|
18
|
+
key = str(mode).lower()
|
|
19
|
+
open_ = float(data.open[-shift]) if shift else float(data.open[0])
|
|
20
|
+
high = float(data.high[-shift]) if shift else float(data.high[0])
|
|
21
|
+
low = float(data.low[-shift]) if shift else float(data.low[0])
|
|
22
|
+
close = float(data.close[-shift]) if shift else float(data.close[0])
|
|
23
|
+
if key in ("close", "1", "price_close"):
|
|
24
|
+
return close
|
|
25
|
+
if key in ("open", "2", "price_open"):
|
|
26
|
+
return open_
|
|
27
|
+
if key in ("high", "3", "price_high"):
|
|
28
|
+
return high
|
|
29
|
+
if key in ("low", "4", "price_low"):
|
|
30
|
+
return low
|
|
31
|
+
if key in ("median", "5", "price_median"):
|
|
32
|
+
return (high + low) / 2.0
|
|
33
|
+
if key in ("typical", "6", "price_typical"):
|
|
34
|
+
return (close + high + low) / 3.0
|
|
35
|
+
if key in ("weighted", "7", "price_weighted"):
|
|
36
|
+
return (2.0 * close + high + low) / 4.0
|
|
37
|
+
if key in ("simple", "8", "price_simpl"):
|
|
38
|
+
return (open_ + close) / 2.0
|
|
39
|
+
if key in ("quarter", "9", "price_quarter"):
|
|
40
|
+
return (open_ + close + high + low) / 4.0
|
|
41
|
+
if key in ("trendfollow0", "10", "price_trendfollow0"):
|
|
42
|
+
if close > open_:
|
|
43
|
+
return high
|
|
44
|
+
if close < open_:
|
|
45
|
+
return low
|
|
46
|
+
return close
|
|
47
|
+
if key in ("trendfollow1", "11", "price_trendfollow1"):
|
|
48
|
+
if close > open_:
|
|
49
|
+
return (high + close) / 2.0
|
|
50
|
+
if close < open_:
|
|
51
|
+
return (low + close) / 2.0
|
|
52
|
+
return close
|
|
53
|
+
return close
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class FineTuningMA(Indicator):
|
|
57
|
+
"""Weighted moving average with rank/shift-shaped per-bar weights."""
|
|
58
|
+
|
|
59
|
+
lines = ("value",)
|
|
60
|
+
params = (
|
|
61
|
+
("ftma", 10),
|
|
62
|
+
("rank1", 2.0),
|
|
63
|
+
("rank2", 2.0),
|
|
64
|
+
("rank3", 2.0),
|
|
65
|
+
("shift1", 1.0),
|
|
66
|
+
("shift2", 1.0),
|
|
67
|
+
("shift3", 1.0),
|
|
68
|
+
("ipc", "typical"),
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
def __init__(self):
|
|
72
|
+
"""Precompute the normalized FineTuningMA weights and warmup period."""
|
|
73
|
+
self.ftma = max(int(self.p.ftma), 1)
|
|
74
|
+
self.weights = []
|
|
75
|
+
total = 0.0
|
|
76
|
+
for h in range(self.ftma):
|
|
77
|
+
denom = max(self.ftma - 1.0, 1.0)
|
|
78
|
+
part = float(h) / denom
|
|
79
|
+
w = self.p.shift1 + math.pow(part, float(self.p.rank1)) * (1.0 - self.p.shift1)
|
|
80
|
+
w = (
|
|
81
|
+
self.p.shift2 + math.pow(1.0 - part, float(self.p.rank2)) * (1.0 - self.p.shift2)
|
|
82
|
+
) * w
|
|
83
|
+
w = (
|
|
84
|
+
self.p.shift3
|
|
85
|
+
+ math.pow(1.0 - abs(part - 0.5) * 2.0, float(self.p.rank3)) * (1.0 - self.p.shift3)
|
|
86
|
+
) * w
|
|
87
|
+
self.weights.append(w)
|
|
88
|
+
total += w
|
|
89
|
+
self.weights = [w / total for w in self.weights] if total else [1.0 / self.ftma] * self.ftma
|
|
90
|
+
self.addminperiod(self.ftma + 2)
|
|
91
|
+
|
|
92
|
+
def next(self):
|
|
93
|
+
"""Output the weighted average of the applied price over the window."""
|
|
94
|
+
if len(self.data) < self.ftma:
|
|
95
|
+
self.l.value[0] = _price_value(self.data, 0, self.p.ipc)
|
|
96
|
+
return
|
|
97
|
+
total = 0.0
|
|
98
|
+
for h in range(self.ftma):
|
|
99
|
+
total += self.weights[h] * _price_value(self.data, h, self.p.ipc)
|
|
100
|
+
self.l.value[0] = total
|
|
@@ -0,0 +1,102 @@
|
|
|
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
|
+
"FisherOrgV1",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _price(data, mode, ago=0):
|
|
18
|
+
"""Return a price value from OHLC data based on a mode selector.
|
|
19
|
+
|
|
20
|
+
Parameters
|
|
21
|
+
----------
|
|
22
|
+
data : DataFeed
|
|
23
|
+
Data feed with open/high/low/close lines.
|
|
24
|
+
mode : int
|
|
25
|
+
Price mode: 2=open, 3=high, 4=low, 5=(h+l)/2, 6=(h+l+c)/3,
|
|
26
|
+
7=(2c+h+l)/4, 8=(o+c)/2, 9=(o+h+l+c)/4; default returns close.
|
|
27
|
+
ago : int
|
|
28
|
+
Bar offset.
|
|
29
|
+
|
|
30
|
+
Returns
|
|
31
|
+
-------
|
|
32
|
+
float
|
|
33
|
+
Selected price value.
|
|
34
|
+
"""
|
|
35
|
+
o = float(data.open[-ago])
|
|
36
|
+
h = float(data.high[-ago])
|
|
37
|
+
low_price = float(data.low[-ago])
|
|
38
|
+
c = float(data.close[-ago])
|
|
39
|
+
if mode == 2:
|
|
40
|
+
return o
|
|
41
|
+
if mode == 3:
|
|
42
|
+
return h
|
|
43
|
+
if mode == 4:
|
|
44
|
+
return low_price
|
|
45
|
+
if mode == 5:
|
|
46
|
+
return (h + low_price) / 2.0
|
|
47
|
+
if mode == 6:
|
|
48
|
+
return (h + low_price + c) / 3.0
|
|
49
|
+
if mode == 7:
|
|
50
|
+
return (2.0 * c + h + low_price) / 4.0
|
|
51
|
+
if mode == 8:
|
|
52
|
+
return (o + c) / 2.0
|
|
53
|
+
if mode == 9:
|
|
54
|
+
return (o + h + low_price + c) / 4.0
|
|
55
|
+
return c
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class FisherOrgV1(Indicator):
|
|
59
|
+
"""Fisher Transform indicator producing a Gaussian-like signal line and its lagged trigger.
|
|
60
|
+
|
|
61
|
+
Lines
|
|
62
|
+
-----
|
|
63
|
+
fisher : float
|
|
64
|
+
Current smoothed Fisher Transform value.
|
|
65
|
+
trigger : float
|
|
66
|
+
Previous bar's fisher value, used for crossover detection.
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
lines = ("fisher", "trigger")
|
|
70
|
+
params = (
|
|
71
|
+
("length", 7),
|
|
72
|
+
("ipc", 1),
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
def __init__(self):
|
|
76
|
+
"""Initialise indicator state and smoothing recursive value."""
|
|
77
|
+
self.addminperiod(int(self.p.length) + 2)
|
|
78
|
+
self._value1 = 0.0
|
|
79
|
+
|
|
80
|
+
def next(self):
|
|
81
|
+
"""Compute Fisher Transform value and set fisher/trigger lines."""
|
|
82
|
+
length = int(self.p.length)
|
|
83
|
+
highs = [float(self.data.high[-i]) for i in range(length)]
|
|
84
|
+
lows = [float(self.data.low[-i]) for i in range(length)]
|
|
85
|
+
smax = max(highs)
|
|
86
|
+
smin = min(lows)
|
|
87
|
+
if smax == smin:
|
|
88
|
+
smax += 1e-12
|
|
89
|
+
price = _price(self.data, int(self.p.ipc), 0)
|
|
90
|
+
wpr = (price - smin) / (smax - smin)
|
|
91
|
+
value0 = (wpr - 0.5) + 0.67 * self._value1
|
|
92
|
+
value0 = min(max(value0, -0.999), 0.999)
|
|
93
|
+
fisher_prev = float(self.lines.fisher[-1]) if len(self) > 1 else 0.0
|
|
94
|
+
if not math.isfinite(fisher_prev):
|
|
95
|
+
fisher_prev = 0.0
|
|
96
|
+
res2 = (1.0 + value0) / (1.0 - value0)
|
|
97
|
+
if res2 < 1e-7:
|
|
98
|
+
res2 = 1.0
|
|
99
|
+
fisher = 0.5 * math.log(res2) + 0.5 * fisher_prev
|
|
100
|
+
self.lines.fisher[0] = fisher
|
|
101
|
+
self.lines.trigger[0] = fisher_prev
|
|
102
|
+
self._value1 = value0
|