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,399 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Yahoo Finance Data Feed Module - Yahoo CSV data parsing.
|
|
3
|
+
|
|
4
|
+
This module provides the YahooFinanceCSVData feed for parsing
|
|
5
|
+
pre-downloaded Yahoo Finance CSV files.
|
|
6
|
+
|
|
7
|
+
Classes:
|
|
8
|
+
YahooFinanceCSVData: Parses Yahoo Finance format CSV files.
|
|
9
|
+
|
|
10
|
+
Example:
|
|
11
|
+
>>> data = bt.feeds.YahooFinanceCSVData(dataname='yahoo.csv')
|
|
12
|
+
>>> cerebro.adddata(data)
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import collections
|
|
16
|
+
import io
|
|
17
|
+
import itertools
|
|
18
|
+
from datetime import date, datetime
|
|
19
|
+
|
|
20
|
+
from .. import feed
|
|
21
|
+
from ..dataseries import TimeFrame
|
|
22
|
+
from ..utils import date2num
|
|
23
|
+
from ..utils.log_message import get_logger
|
|
24
|
+
|
|
25
|
+
logger = get_logger(__name__)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class YahooFinanceCSVData(feed.CSVDataBase):
|
|
29
|
+
"""
|
|
30
|
+
Parses pre-downloaded Yahoo CSV Data Feeds (or locally generated if they
|
|
31
|
+
comply to the Yahoo format)
|
|
32
|
+
|
|
33
|
+
Specific parameters:
|
|
34
|
+
|
|
35
|
+
- ``dataname``
|
|
36
|
+
|
|
37
|
+
The filename to parse or a file-like object
|
|
38
|
+
|
|
39
|
+
- ``reverse``
|
|
40
|
+
|
|
41
|
+
It is assumed that locally stored files have the newest lines at the
|
|
42
|
+
bottom
|
|
43
|
+
|
|
44
|
+
If this is not the case, pass *reverse* = ``True``
|
|
45
|
+
|
|
46
|
+
- ``adjclose`` (default: ``True``)
|
|
47
|
+
Whether to use the dividend/split adjusted close and adjust all
|
|
48
|
+
values according to it.
|
|
49
|
+
|
|
50
|
+
- ``adjvolume`` (default: ``True``)
|
|
51
|
+
Do also adjust ``volume`` if ``adjclose`` is also ``True``
|
|
52
|
+
|
|
53
|
+
- ``round`` (default: ``True``)
|
|
54
|
+
Whether to round the values to a specific number of decimals after
|
|
55
|
+
having adjusted the close
|
|
56
|
+
|
|
57
|
+
- ``roundvolume`` (default: ``0``)
|
|
58
|
+
Round the resulting volume to the given number of decimals after having
|
|
59
|
+
adjusted it
|
|
60
|
+
|
|
61
|
+
- ``decimals`` (default: ``2``)
|
|
62
|
+
Number of decimals to round to
|
|
63
|
+
|
|
64
|
+
- ``swapcloses`` (default: ``False``)
|
|
65
|
+
[2018-11-16] It would seem that the order of *close* and *adjusted
|
|
66
|
+
close* is now fixed. The parameter is retained, in case the need to
|
|
67
|
+
swap the columns again arose.
|
|
68
|
+
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
# Add a line
|
|
72
|
+
lines = ("adjclose",)
|
|
73
|
+
|
|
74
|
+
params = (
|
|
75
|
+
("reverse", False),
|
|
76
|
+
("adjclose", True),
|
|
77
|
+
("adjvolume", True),
|
|
78
|
+
("round", True),
|
|
79
|
+
("decimals", 2),
|
|
80
|
+
("roundvolume", False),
|
|
81
|
+
("swapcloses", False),
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
def start(self):
|
|
85
|
+
"""Start the Yahoo Finance CSV data feed.
|
|
86
|
+
|
|
87
|
+
Reverses data order if needed for correct chronological sequence.
|
|
88
|
+
"""
|
|
89
|
+
super().start()
|
|
90
|
+
# If reverse is False, return directly, don't run code below
|
|
91
|
+
if not self.params.reverse:
|
|
92
|
+
return
|
|
93
|
+
|
|
94
|
+
# Yahoo sends data in reverse order and the file is still unreversed
|
|
95
|
+
# Use deque double-ended queue, appending to left is much more efficient than list.
|
|
96
|
+
# If file dates are reversed, data is reversed during transfer, so dates in new file are in correct order
|
|
97
|
+
dq: collections.deque = collections.deque()
|
|
98
|
+
for line in self.f:
|
|
99
|
+
dq.appendleft(line)
|
|
100
|
+
# Create a string buffer object, write queue data to file, move pointer to 0th character, close file, assign file to self.f
|
|
101
|
+
f = io.StringIO(newline=None)
|
|
102
|
+
f.writelines(dq)
|
|
103
|
+
f.seek(0)
|
|
104
|
+
self.f.close()
|
|
105
|
+
self.f = f
|
|
106
|
+
|
|
107
|
+
def _loadline(self, linetokens):
|
|
108
|
+
# _loadline code is relatively familiar, all quite similar
|
|
109
|
+
# A while loop
|
|
110
|
+
while True:
|
|
111
|
+
nullseen = False
|
|
112
|
+
for tok in linetokens[1:]:
|
|
113
|
+
if tok == "null":
|
|
114
|
+
nullseen = True
|
|
115
|
+
linetokens = self._getnextline() # refetch tokens
|
|
116
|
+
if not linetokens:
|
|
117
|
+
return False # cannot fetch, go away
|
|
118
|
+
|
|
119
|
+
# out of for to carry on wiwth while True logic
|
|
120
|
+
break
|
|
121
|
+
|
|
122
|
+
if not nullseen:
|
|
123
|
+
break # can proceed
|
|
124
|
+
# Counter, value increases by 1 when calling next(i)
|
|
125
|
+
i = itertools.count(0)
|
|
126
|
+
# Get time string
|
|
127
|
+
dttxt = linetokens[next(i)]
|
|
128
|
+
# Generate time
|
|
129
|
+
dt = date(int(dttxt[0:4]), int(dttxt[5:7]), int(dttxt[8:10]))
|
|
130
|
+
# Convert time to number
|
|
131
|
+
dtnum = date2num(datetime.combine(dt, self.p.sessionend))
|
|
132
|
+
# Assign value to datetime line
|
|
133
|
+
self.lines.datetime[0] = dtnum
|
|
134
|
+
# Get open, high, low, close, open interest
|
|
135
|
+
o = float(linetokens[next(i)])
|
|
136
|
+
h = float(linetokens[next(i)])
|
|
137
|
+
low = float(linetokens[next(i)])
|
|
138
|
+
c = float(linetokens[next(i)])
|
|
139
|
+
self.lines.openinterest[0] = 0.0
|
|
140
|
+
|
|
141
|
+
# 2018-11-16 ... Adjusted Close seems to always be delivered after
|
|
142
|
+
# the close and before the volume columns
|
|
143
|
+
# Get adjusted price
|
|
144
|
+
adjustedclose = float(linetokens[next(i)])
|
|
145
|
+
# Try to get volume, if not available, set to 0
|
|
146
|
+
try:
|
|
147
|
+
v = float(linetokens[next(i)])
|
|
148
|
+
except (ValueError, TypeError, IndexError, StopIteration) as e:
|
|
149
|
+
# cover the case in which volume is "null" / missing
|
|
150
|
+
logger.warning("volume parse failed, defaulting to 0.0: %s", e)
|
|
151
|
+
v = 0.0
|
|
152
|
+
# If swapping close price and adjusted close price, perform swap
|
|
153
|
+
if self.p.swapcloses: # swap closing prices if requested
|
|
154
|
+
c, adjustedclose = adjustedclose, c
|
|
155
|
+
# Calculate adjustment factor, the calculation method seems different from conventional usage, but not necessarily wrong
|
|
156
|
+
adjfactor = c / adjustedclose if adjustedclose != 0.0 else 1.0
|
|
157
|
+
|
|
158
|
+
# in v7 "adjusted prices" seem to be given, scale back for non adj
|
|
159
|
+
# If price adjustment is needed, divide by adjustment factor
|
|
160
|
+
if self.params.adjclose:
|
|
161
|
+
o /= adjfactor
|
|
162
|
+
h /= adjfactor
|
|
163
|
+
low /= adjfactor
|
|
164
|
+
c = adjustedclose
|
|
165
|
+
# If the price goes down, volume must go up and viceversa
|
|
166
|
+
# If adjusting volume
|
|
167
|
+
if self.p.adjvolume:
|
|
168
|
+
v *= adjfactor
|
|
169
|
+
# If rounding is needed, round the prices
|
|
170
|
+
if self.p.round:
|
|
171
|
+
decimals = self.p.decimals
|
|
172
|
+
o = round(o, decimals)
|
|
173
|
+
h = round(h, decimals)
|
|
174
|
+
low = round(low, decimals)
|
|
175
|
+
c = round(c, decimals)
|
|
176
|
+
# Round the volume
|
|
177
|
+
v = round(v, self.p.roundvolume)
|
|
178
|
+
# Assign calculated data to corresponding lines
|
|
179
|
+
self.lines.open[0] = o
|
|
180
|
+
self.lines.high[0] = h
|
|
181
|
+
self.lines.low[0] = low
|
|
182
|
+
self.lines.close[0] = c
|
|
183
|
+
self.lines.volume[0] = v
|
|
184
|
+
self.lines.adjclose[0] = adjustedclose
|
|
185
|
+
|
|
186
|
+
return True
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
class YahooLegacyCSV(YahooFinanceCSVData):
|
|
190
|
+
"""
|
|
191
|
+
This is intended to load files which were downloaded before Yahoo
|
|
192
|
+
discontinued the original service in May-2017
|
|
193
|
+
Used to load data downloaded before May 2017
|
|
194
|
+
"""
|
|
195
|
+
|
|
196
|
+
params = (("version", ""),)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
class YahooFinanceCSV(feed.CSVFeedBase):
|
|
200
|
+
"""Yahoo Finance CSV feed class.
|
|
201
|
+
|
|
202
|
+
Wrapper class for YahooFinanceCSVData feed functionality.
|
|
203
|
+
"""
|
|
204
|
+
|
|
205
|
+
DataCls = YahooFinanceCSVData
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
class YahooFinanceData(YahooFinanceCSVData):
|
|
209
|
+
# This is a method to directly crawl data from Yahoo
|
|
210
|
+
"""
|
|
211
|
+
Executes a direct download of data from Yahoo servers for the given time
|
|
212
|
+
range.
|
|
213
|
+
|
|
214
|
+
Specific parameters (or specific meaning):
|
|
215
|
+
|
|
216
|
+
- ``dataname``
|
|
217
|
+
|
|
218
|
+
The ticker to download ('YHOO' for Yahoo own stock quotes)
|
|
219
|
+
|
|
220
|
+
- ``proxies``
|
|
221
|
+
|
|
222
|
+
A dict indicating which proxy to go through for the download as in
|
|
223
|
+
{'http': 'http://myproxy.com'} or {'http': 'http://127.0.0.1:8080'}
|
|
224
|
+
|
|
225
|
+
- ``period``
|
|
226
|
+
|
|
227
|
+
The timeframe to download data in. Pass 'w' for weekly and 'm' for
|
|
228
|
+
monthly.
|
|
229
|
+
|
|
230
|
+
- ``reverse``
|
|
231
|
+
|
|
232
|
+
[2018-11-16] The latest incarnation of Yahoo online downloads returns
|
|
233
|
+
the data in the proper order. The default value of ``reverse`` for the
|
|
234
|
+
online download is therefore set to ``False``
|
|
235
|
+
|
|
236
|
+
- ``adjclose``
|
|
237
|
+
|
|
238
|
+
Whether to use the dividend/split adjusted close and adjust all values
|
|
239
|
+
according to it.
|
|
240
|
+
|
|
241
|
+
- ``urlhist``
|
|
242
|
+
|
|
243
|
+
The url of the historical quotes in Yahoo Finance used to gather a
|
|
244
|
+
``crumb`` authorization cookie for the download
|
|
245
|
+
|
|
246
|
+
- ``urldown``
|
|
247
|
+
|
|
248
|
+
The url of the actual download server
|
|
249
|
+
|
|
250
|
+
- ``retries``
|
|
251
|
+
|
|
252
|
+
Number of times (each) to try to get a ``crumb`` cookie and download
|
|
253
|
+
the data
|
|
254
|
+
|
|
255
|
+
"""
|
|
256
|
+
|
|
257
|
+
params: tuple = (
|
|
258
|
+
("proxies", {}),
|
|
259
|
+
("period", "d"),
|
|
260
|
+
("reverse", False),
|
|
261
|
+
("urlhist", "https://finance.yahoo.com/quote/{}/history"),
|
|
262
|
+
("urldown", "https://query1.finance.yahoo.com/v7/finance/download"),
|
|
263
|
+
("retries", 3),
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
def __init__(self):
|
|
267
|
+
"""Initialize the Yahoo Finance data feed.
|
|
268
|
+
|
|
269
|
+
Sets up error tracking for data downloads.
|
|
270
|
+
"""
|
|
271
|
+
self.error = None
|
|
272
|
+
|
|
273
|
+
def start_v7(self):
|
|
274
|
+
"""Start Yahoo Finance data download using v7 API.
|
|
275
|
+
|
|
276
|
+
Fetches crumb cookie and downloads historical data.
|
|
277
|
+
"""
|
|
278
|
+
try:
|
|
279
|
+
import requests
|
|
280
|
+
except ImportError:
|
|
281
|
+
msg = (
|
|
282
|
+
"The new Yahoo data feed requires to have the requests "
|
|
283
|
+
"module installed. Please use pip install requests or "
|
|
284
|
+
"the method of your choice"
|
|
285
|
+
)
|
|
286
|
+
raise ImportError(msg) from None
|
|
287
|
+
|
|
288
|
+
self.error = None
|
|
289
|
+
url = self.p.urlhist.format(self.p.dataname)
|
|
290
|
+
|
|
291
|
+
sesskwargs = {}
|
|
292
|
+
if self.p.proxies:
|
|
293
|
+
sesskwargs["proxies"] = self.p.proxies
|
|
294
|
+
|
|
295
|
+
crumb = None
|
|
296
|
+
sess = requests.Session()
|
|
297
|
+
for i in range(self.p.retries + 1): # at least once
|
|
298
|
+
resp = sess.get(url, **sesskwargs)
|
|
299
|
+
if resp.status_code != requests.codes.ok:
|
|
300
|
+
continue
|
|
301
|
+
|
|
302
|
+
txt = resp.text
|
|
303
|
+
i = txt.find("CrumbStore")
|
|
304
|
+
if i == -1:
|
|
305
|
+
continue
|
|
306
|
+
i = txt.find("crumb", i)
|
|
307
|
+
if i == -1:
|
|
308
|
+
continue
|
|
309
|
+
istart = txt.find('"', i + len("crumb") + 1)
|
|
310
|
+
if istart == -1:
|
|
311
|
+
continue
|
|
312
|
+
istart += 1
|
|
313
|
+
iend = txt.find('"', istart)
|
|
314
|
+
if iend == -1:
|
|
315
|
+
continue
|
|
316
|
+
|
|
317
|
+
crumb = txt[istart:iend]
|
|
318
|
+
crumb = crumb.encode("ascii").decode("unicode-escape")
|
|
319
|
+
break
|
|
320
|
+
|
|
321
|
+
if crumb is None:
|
|
322
|
+
self.error = "Crumb not found"
|
|
323
|
+
self.f = None
|
|
324
|
+
return
|
|
325
|
+
|
|
326
|
+
from ..utils.py3 import urlquote
|
|
327
|
+
|
|
328
|
+
crumb = urlquote(crumb)
|
|
329
|
+
|
|
330
|
+
# urldown/ticker?period1=posix1&period2=posix2&interval=1d&events=history&crumb=crumb
|
|
331
|
+
|
|
332
|
+
# Try to download
|
|
333
|
+
urld = f"{self.p.urldown}/{self.p.dataname}"
|
|
334
|
+
|
|
335
|
+
urlargs = []
|
|
336
|
+
posix = date(1970, 1, 1)
|
|
337
|
+
if self.p.todate is not None:
|
|
338
|
+
period2 = (self.p.todate.date() - posix).total_seconds()
|
|
339
|
+
urlargs.append(f"period2={int(period2)}")
|
|
340
|
+
|
|
341
|
+
if self.p.todate is not None:
|
|
342
|
+
period1 = (self.p.fromdate.date() - posix).total_seconds()
|
|
343
|
+
urlargs.append(f"period1={int(period1)}")
|
|
344
|
+
|
|
345
|
+
intervals = {
|
|
346
|
+
TimeFrame.Days: "1d",
|
|
347
|
+
TimeFrame.Weeks: "1wk",
|
|
348
|
+
TimeFrame.Months: "1mo",
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
urlargs.append(f"interval={intervals[self.p.timeframe]}")
|
|
352
|
+
urlargs.append("events=history")
|
|
353
|
+
urlargs.append(f"crumb={crumb}")
|
|
354
|
+
|
|
355
|
+
urld = "{}?{}".format(urld, "&".join(urlargs))
|
|
356
|
+
f = None
|
|
357
|
+
for i in range(self.p.retries + 1): # at least once
|
|
358
|
+
resp = sess.get(urld, **sesskwargs)
|
|
359
|
+
if resp.status_code != requests.codes.ok:
|
|
360
|
+
continue
|
|
361
|
+
|
|
362
|
+
ctype = resp.headers["Content-Type"]
|
|
363
|
+
# Cover as many text types as possible for Yahoo changes
|
|
364
|
+
if not ctype.startswith("text/"):
|
|
365
|
+
self.error = "Wrong content type: %s" % ctype
|
|
366
|
+
continue # HTML returned? wrong url?
|
|
367
|
+
|
|
368
|
+
# buffer everything from the socket into a local buffer
|
|
369
|
+
try:
|
|
370
|
+
# r.encoding = 'UTF-8'
|
|
371
|
+
f = io.StringIO(resp.text, newline=None)
|
|
372
|
+
except Exception as e:
|
|
373
|
+
logger.warning("Yahoo response read failed, retrying: %s", e)
|
|
374
|
+
continue # try again if possible
|
|
375
|
+
|
|
376
|
+
break
|
|
377
|
+
|
|
378
|
+
self.f = f
|
|
379
|
+
|
|
380
|
+
def start(self):
|
|
381
|
+
"""Start the Yahoo Finance data feed.
|
|
382
|
+
|
|
383
|
+
Initiates download and prepares CSV parser.
|
|
384
|
+
"""
|
|
385
|
+
self.start_v7()
|
|
386
|
+
|
|
387
|
+
# Prepared a "path" file - CSV Parser can take over
|
|
388
|
+
super().start()
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
class YahooFinance(feed.CSVFeedBase):
|
|
392
|
+
"""Yahoo Finance feed class.
|
|
393
|
+
|
|
394
|
+
Wrapper class for YahooFinanceData feed functionality.
|
|
395
|
+
"""
|
|
396
|
+
|
|
397
|
+
DataCls = YahooFinanceData
|
|
398
|
+
# Get specific parameters and form tuple
|
|
399
|
+
params = DataCls.params._gettuple()
|
backtrader/fillers.py
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Fillers Module - Order execution size calculation.
|
|
3
|
+
|
|
4
|
+
This module provides filler classes that determine how much of an order
|
|
5
|
+
can be executed based on available volume, price constraints, and
|
|
6
|
+
user-defined parameters.
|
|
7
|
+
|
|
8
|
+
Classes:
|
|
9
|
+
FixedSize: Execute with fixed maximum size.
|
|
10
|
+
FixedBarPerc: Execute using percentage of bar volume.
|
|
11
|
+
BarPointPerc: Execute distributing volume across price range.
|
|
12
|
+
|
|
13
|
+
Example:
|
|
14
|
+
>>> cerebro.broker.set_filler(backtrader.fillers.FixedBarPerc(perc=50.0))
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from .parameters import ParameterizedBase
|
|
18
|
+
from .utils.py3 import MAXINT
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# Fixed size filtering, when order executes can only trade current volume, need minimum of order quantity and size, if size is None, ignore size
|
|
22
|
+
class FixedSize(ParameterizedBase):
|
|
23
|
+
"""Returns the execution size for a given order using a *percentage* of the
|
|
24
|
+
volume in a bar.
|
|
25
|
+
|
|
26
|
+
This percentage is set with the parameter ``perc``
|
|
27
|
+
|
|
28
|
+
Params:
|
|
29
|
+
|
|
30
|
+
- ``size`` (default: ``None``) maximum size to be executed.
|
|
31
|
+
The actual
|
|
32
|
+
volume of the bar at execution time is also a limit if smaller than the
|
|
33
|
+
size
|
|
34
|
+
|
|
35
|
+
If the value of this parameter evaluates to False, the entire volume
|
|
36
|
+
of the bar will be used to match the order
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
params = (("size", None),)
|
|
40
|
+
|
|
41
|
+
def __call__(self, order, price, ago):
|
|
42
|
+
"""Calculate the execution size for an order.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
order: The order being executed.
|
|
46
|
+
price: Execution price.
|
|
47
|
+
ago: Number of bars back (0 for current, -1 for previous).
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
float: The maximum size that can be executed, limited by
|
|
51
|
+
bar volume, remaining order size, and configured size.
|
|
52
|
+
"""
|
|
53
|
+
size = self.p.size or MAXINT
|
|
54
|
+
return min((order.data.volume[ago], abs(order.executed.remsize), size))
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# Fixed percentage, use a certain percentage of current volume and compare with order quantity, choose minimum for trading
|
|
58
|
+
class FixedBarPerc(ParameterizedBase):
|
|
59
|
+
"""Returns the execution size for a given order using a *percentage* of the
|
|
60
|
+
volume in a bar.
|
|
61
|
+
|
|
62
|
+
This percentage is set with the parameter ``perc``
|
|
63
|
+
|
|
64
|
+
Params:
|
|
65
|
+
|
|
66
|
+
- ``perc`` (default: ``100.0``) (valied values: ``0.0-100.0``)
|
|
67
|
+
|
|
68
|
+
Percentage of the volume bar to use to execute an order
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
params = (("perc", 100.0),)
|
|
72
|
+
|
|
73
|
+
def __call__(self, order, price, ago):
|
|
74
|
+
"""Calculate the execution size using percentage of bar volume.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
order: The order being executed.
|
|
78
|
+
price: Execution price.
|
|
79
|
+
ago: Number of bars back (0 for current, -1 for previous).
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
float: The maximum size that can be executed based on
|
|
83
|
+
percentage of bar volume and remaining order size.
|
|
84
|
+
"""
|
|
85
|
+
# Get the volume and scale it to the requested perc
|
|
86
|
+
maxsize = (order.data.volume[ago] * self.p.perc) // 100
|
|
87
|
+
# Return the maximum possible executed volume
|
|
88
|
+
return min(maxsize, abs(order.executed.remsize))
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
# Distribute according to bar's fluctuation range by percentage
|
|
92
|
+
class BarPointPerc(ParameterizedBase):
|
|
93
|
+
"""Returns the execution size for a given order. The volume will be
|
|
94
|
+
distributed uniformly in the range *high*-*low* using ``minmov`` to
|
|
95
|
+
partition.
|
|
96
|
+
|
|
97
|
+
From the allocated volume for the given price, the `perc` percentage will
|
|
98
|
+
be used
|
|
99
|
+
|
|
100
|
+
Params:
|
|
101
|
+
|
|
102
|
+
- ``minmov`` (default: ``0.01``)
|
|
103
|
+
|
|
104
|
+
Minimum price movement. Used to partition the range *high*-*low* to
|
|
105
|
+
proportionally distribute the volume amongst possible prices
|
|
106
|
+
|
|
107
|
+
- ``perc`` (default: ``100.0``) (valied values: ``0.0-100.0``)
|
|
108
|
+
|
|
109
|
+
Percentage of the volume allocated to the order execution price to use
|
|
110
|
+
for matching
|
|
111
|
+
# minmov defaults to 0.01, based on distance between high and low prices, see how many parts can be divided
|
|
112
|
+
# perc defaults to 100, trading limit is order can only be placed for each part's perc
|
|
113
|
+
"""
|
|
114
|
+
|
|
115
|
+
# Specific parameters
|
|
116
|
+
params = (
|
|
117
|
+
("minmov", None),
|
|
118
|
+
("perc", 100.0),
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
def __call__(self, order, price, ago):
|
|
122
|
+
"""Calculate the execution size distributing volume across price range.
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
order: The order being executed.
|
|
126
|
+
price: Execution price.
|
|
127
|
+
ago: Number of bars back (0 for current, -1 for previous).
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
float: The maximum size that can be executed based on
|
|
131
|
+
proportional distribution across the price range.
|
|
132
|
+
"""
|
|
133
|
+
# Data
|
|
134
|
+
data = order.data
|
|
135
|
+
# Minimum price movement
|
|
136
|
+
minmov = self.p.minmov
|
|
137
|
+
# Calculate how many parts can be divided
|
|
138
|
+
parts = 1
|
|
139
|
+
if minmov:
|
|
140
|
+
# high - low + minmov to account for open-ended minus op
|
|
141
|
+
parts = (data.high[ago] - data.low[ago] + minmov) // minmov
|
|
142
|
+
if parts < 1:
|
|
143
|
+
parts = 1
|
|
144
|
+
# Calculate how much each part can trade
|
|
145
|
+
alloc_vol = ((data.volume[ago] / parts) * self.p.perc) // 100.0
|
|
146
|
+
# return max possible executable volume
|
|
147
|
+
# Return maximum possible executable order quantity
|
|
148
|
+
return min(alloc_vol, abs(order.executed.remsize))
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Data Filters Module - Data transformation and filtering.
|
|
3
|
+
|
|
4
|
+
This module provides filter classes for transforming and filtering
|
|
5
|
+
data feeds. Filters can be used to resample data, fill missing values,
|
|
6
|
+
calculate derived data types like Heikin Ashi candles, and more.
|
|
7
|
+
|
|
8
|
+
Available Filters:
|
|
9
|
+
- CalendarDays: Filter for calendar day operations.
|
|
10
|
+
- DataFilter: Base class for data filtering.
|
|
11
|
+
- DataFiller: Fill missing data values.
|
|
12
|
+
- DaySteps: Filter for day step operations.
|
|
13
|
+
- HeikinAshi: Calculate Heikin Ashi candles.
|
|
14
|
+
- Renko: Calculate Renko bricks.
|
|
15
|
+
- Session: Filter for session operations.
|
|
16
|
+
- BSplitter: Split data into multiple parts.
|
|
17
|
+
|
|
18
|
+
Example:
|
|
19
|
+
Using a filter with data:
|
|
20
|
+
>>> data = bt.feeds.GenericCSVData(dataname='data.csv')
|
|
21
|
+
>>> cerebro.adddata(data)
|
|
22
|
+
>>> cerebro.adddata(bt.feeds.GenericCSVData(dataname='data2.csv'),
|
|
23
|
+
... filter=bt.filters.HeikinAshi())
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from ..flt import Filter as Filter
|
|
27
|
+
from .bsplitter import *
|
|
28
|
+
from .calendardays import *
|
|
29
|
+
from .datafiller import *
|
|
30
|
+
from .datafilter import *
|
|
31
|
+
from .daysteps import *
|
|
32
|
+
from .heikinashi import *
|
|
33
|
+
from .renko import *
|
|
34
|
+
from .session import *
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Bar Splitter Filter Module - Daily bar splitting.
|
|
3
|
+
|
|
4
|
+
This module provides the DaySplitterClose filter for splitting daily
|
|
5
|
+
bars into two parts for intraday replay simulation.
|
|
6
|
+
|
|
7
|
+
Classes:
|
|
8
|
+
DaySplitterClose: Splits daily bars into OHLX and CCCC ticks.
|
|
9
|
+
|
|
10
|
+
Example:
|
|
11
|
+
>>> data = bt.feeds.GenericCSVData(dataname='daily.csv')
|
|
12
|
+
>>> data.addfilter(bt.filters.DaySplitterClose())
|
|
13
|
+
>>> cerebro.adddata(data)
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import datetime
|
|
17
|
+
|
|
18
|
+
from backtrader.parameters import ParameterizedBase
|
|
19
|
+
|
|
20
|
+
__all__ = ["DaySplitterClose", "DaySplitter_Close"]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class DaySplitterClose(ParameterizedBase):
|
|
24
|
+
"""
|
|
25
|
+
Splits a daily bar in two parts simulating 2 ticks which will be used to
|
|
26
|
+
replay the data:
|
|
27
|
+
|
|
28
|
+
- First tick: ``OHLX``
|
|
29
|
+
|
|
30
|
+
The ``Close`` will be replaced by the *average* of ``Open``, ``High``
|
|
31
|
+
and ``Low``
|
|
32
|
+
|
|
33
|
+
The session opening time is used for this tick
|
|
34
|
+
|
|
35
|
+
And
|
|
36
|
+
|
|
37
|
+
- Second tick: ``CCCC``
|
|
38
|
+
|
|
39
|
+
The `Close` price will be used for the four components of the price
|
|
40
|
+
|
|
41
|
+
The session closing time is used for this tick
|
|
42
|
+
|
|
43
|
+
The volume will be split amongst the 2 ticks using the parameters:
|
|
44
|
+
|
|
45
|
+
- ``closevol`` (default: ``0.5``) The value indicates which percentage, in
|
|
46
|
+
absolute terms from 0.0 to 1.0, has to be assigned to the *closing*
|
|
47
|
+
tick. The rest will be assigned to the ``OHLX`` tick.
|
|
48
|
+
|
|
49
|
+
**This filter is meant to be used together with** ``cerebro.replaydata``
|
|
50
|
+
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
params = (("closevol", 0.5),) # 0 -> 1 amount of volume to keep for close
|
|
54
|
+
|
|
55
|
+
# replaying = True
|
|
56
|
+
|
|
57
|
+
def __init__(self, data, **kwargs):
|
|
58
|
+
"""Initialize the DaySplitterClose filter.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
data: The data feed to apply the filter to.
|
|
62
|
+
**kwargs: Additional keyword arguments passed to parent class.
|
|
63
|
+
"""
|
|
64
|
+
super().__init__(**kwargs)
|
|
65
|
+
self.lastdt = None
|
|
66
|
+
|
|
67
|
+
def __call__(self, data):
|
|
68
|
+
"""Process the data feed to split daily bars.
|
|
69
|
+
|
|
70
|
+
This method is called for each bar in the data feed. It splits the daily
|
|
71
|
+
bar into two parts - an OHLX tick and a CCCC tick - to simulate intraday
|
|
72
|
+
trading behavior.
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
data: The data feed containing the bar to process.
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
bool: False if the initial tick can be further processed from stack.
|
|
79
|
+
"""
|
|
80
|
+
# Make a copy of the new bar and remove it from stream
|
|
81
|
+
datadt = data.datetime.date() # keep the date
|
|
82
|
+
|
|
83
|
+
if self.lastdt == datadt:
|
|
84
|
+
return False # skip bars that come again in the filter
|
|
85
|
+
|
|
86
|
+
self.lastdt = datadt # keep ref to last seen bar
|
|
87
|
+
|
|
88
|
+
# Make a copy of current data for ohlbar
|
|
89
|
+
ohlbar = [data.lines[i][0] for i in range(data.size())]
|
|
90
|
+
closebar = ohlbar[:] # Make a copy for the close
|
|
91
|
+
|
|
92
|
+
# replace close price with o-h-l average
|
|
93
|
+
ohlprice = ohlbar[data.Open] + ohlbar[data.High] + ohlbar[data.Low]
|
|
94
|
+
ohlbar[data.Close] = ohlprice / 3.0
|
|
95
|
+
|
|
96
|
+
vol = ohlbar[data.Volume] # adjust volume
|
|
97
|
+
ohlbar[data.Volume] = vohl = int(vol * (1.0 - self.p.closevol))
|
|
98
|
+
|
|
99
|
+
oi = ohlbar[data.OpenInterest] # adjust open interst
|
|
100
|
+
ohlbar[data.OpenInterest] = 0
|
|
101
|
+
|
|
102
|
+
# Adjust times
|
|
103
|
+
dt = datetime.datetime.combine(datadt, data.p.sessionstart)
|
|
104
|
+
ohlbar[data.DateTime] = data.date2num(dt)
|
|
105
|
+
|
|
106
|
+
# Ajust closebar to generate a single tick -> close price
|
|
107
|
+
closebar[data.Open] = cprice = closebar[data.Close]
|
|
108
|
+
closebar[data.High] = cprice
|
|
109
|
+
closebar[data.Low] = cprice
|
|
110
|
+
closebar[data.Volume] = vol - vohl
|
|
111
|
+
ohlbar[data.OpenInterest] = oi
|
|
112
|
+
|
|
113
|
+
# Adjust times
|
|
114
|
+
dt = datetime.datetime.combine(datadt, data.p.sessionend)
|
|
115
|
+
closebar[data.DateTime] = data.date2num(dt)
|
|
116
|
+
|
|
117
|
+
# Update stream
|
|
118
|
+
data.backwards(force=True) # remove the copied bar from stream
|
|
119
|
+
data._add2stack(ohlbar) # add ohlbar to stack
|
|
120
|
+
# Add 2nd part to stash to delay processing to next round
|
|
121
|
+
data._add2stack(closebar, stash=True)
|
|
122
|
+
|
|
123
|
+
return False # initial tick can be further processed from stack
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
# Alias for backward compatibility
|
|
127
|
+
DaySplitter_Close = DaySplitterClose
|