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,229 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Rollover Data Feed Module - Futures contract rollover.
|
|
3
|
+
|
|
4
|
+
This module provides the RollOver feed for automatically rolling over
|
|
5
|
+
to the next futures contract when conditions are met.
|
|
6
|
+
|
|
7
|
+
Classes:
|
|
8
|
+
RollOver: Rolls over to the next future when conditions are met.
|
|
9
|
+
|
|
10
|
+
Example:
|
|
11
|
+
>>> data_old = bt.feeds.BacktraderCSVData(dataname='contract_old.csv')
|
|
12
|
+
>>> data_new = bt.feeds.BacktraderCSVData(dataname='contract_new.csv')
|
|
13
|
+
>>> data = bt.feeds.RollOver(data_old, data_new, checkdate=my_check_func)
|
|
14
|
+
>>> cerebro.adddata(data)
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from datetime import datetime
|
|
18
|
+
|
|
19
|
+
from ..feed import DataBase
|
|
20
|
+
from ..utils.date import Localizer
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class RollOver(DataBase):
|
|
24
|
+
# Roll over to the next future when conditions are met
|
|
25
|
+
"""Class that rolls over to the next future when a condition is met
|
|
26
|
+
|
|
27
|
+
Params:
|
|
28
|
+
|
|
29
|
+
- ``checkdate`` (default: ``None``)
|
|
30
|
+
|
|
31
|
+
This must be a *callable* with the following signature::
|
|
32
|
+
|
|
33
|
+
Checkdate(dt, d):
|
|
34
|
+
|
|
35
|
+
Where:
|
|
36
|
+
|
|
37
|
+
- ``dt`` is a ``datetime.datetime`` object
|
|
38
|
+
- ``d`` is the current data feed for the active future
|
|
39
|
+
|
|
40
|
+
Expected Return Values:
|
|
41
|
+
|
|
42
|
+
- ``True``: as long as the callable returns this, a switchover can
|
|
43
|
+
happen to the next future
|
|
44
|
+
|
|
45
|
+
If a commodity expires on the 3rd Friday of March, `checkdate` could
|
|
46
|
+
return `True` for the entire week in which the expiration takes
|
|
47
|
+
place.
|
|
48
|
+
|
|
49
|
+
- ``False``: the expiration cannot take place
|
|
50
|
+
|
|
51
|
+
# This parameter is a callable object checkdate(dt,d), where dt is a time object, d is current active data,
|
|
52
|
+
# If return value is True, will switch to next contract; if False, will not switch to next contract
|
|
53
|
+
|
|
54
|
+
- ``checkcondition`` (default: ``None``)
|
|
55
|
+
|
|
56
|
+
**Note**: This will only be called if ``checkdate`` has returned
|
|
57
|
+
``True``
|
|
58
|
+
|
|
59
|
+
If ``None`` this will evaluate to ``True`` (execute roll over)
|
|
60
|
+
internally
|
|
61
|
+
|
|
62
|
+
Else this must be a *callable* with this signature::
|
|
63
|
+
|
|
64
|
+
Checkcondition(d0, d1)
|
|
65
|
+
|
|
66
|
+
Where:
|
|
67
|
+
|
|
68
|
+
- ``d0`` is the current data feed for the active future
|
|
69
|
+
- ``d1`` is the data feed for the next expiration
|
|
70
|
+
|
|
71
|
+
Expected Return Values:
|
|
72
|
+
|
|
73
|
+
- ``True``: roll-over to the next future
|
|
74
|
+
|
|
75
|
+
Following with the example from ``checkdate``, this could say that the
|
|
76
|
+
roll-over can only happen if the *volume* from ``d0`` is already less
|
|
77
|
+
than the volume from ``d1``
|
|
78
|
+
|
|
79
|
+
- ``False``: the expiration cannot take place
|
|
80
|
+
# When checkdate returns True, this function will be called, this must be a callable object, checkcondition(d0,d1)
|
|
81
|
+
# Where d0 is current active futures contract, d1 is next expiring contract, if True, will switch from d0 to d1, if not, switch will not happen.
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
params = (
|
|
85
|
+
# ('rolls', []), # array of futures to roll over
|
|
86
|
+
("checkdate", None), # callable
|
|
87
|
+
("checkcondition", None), # callable
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
def islive(self):
|
|
91
|
+
# Make data live form, will avoid preloading and runonce
|
|
92
|
+
"""Returns ``True`` to notify ``Cerebro`` that preloading and runonce
|
|
93
|
+
should be deactivated"""
|
|
94
|
+
return True
|
|
95
|
+
|
|
96
|
+
def __init__(self, *args, **kwargs):
|
|
97
|
+
"""Initialize the RollOver data feed.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
*args: Data feeds to roll over between.
|
|
101
|
+
**kwargs: Keyword arguments for data feed configuration.
|
|
102
|
+
"""
|
|
103
|
+
# Handle timeframe and compression parameters, originally handled by metaclass
|
|
104
|
+
if args:
|
|
105
|
+
# Copy timeframe and compression from first data source
|
|
106
|
+
kwargs.setdefault("timeframe", getattr(args[0], "_timeframe", None))
|
|
107
|
+
kwargs.setdefault("compression", getattr(args[0], "_compression", None))
|
|
108
|
+
|
|
109
|
+
super().__init__(**kwargs)
|
|
110
|
+
|
|
111
|
+
# Prepare futures contracts for rollover
|
|
112
|
+
self._dts = None
|
|
113
|
+
self._dexp = None
|
|
114
|
+
self._d = None
|
|
115
|
+
self._ds = None
|
|
116
|
+
self._rolls = args
|
|
117
|
+
|
|
118
|
+
def start(self):
|
|
119
|
+
"""Start the RollOver data feed.
|
|
120
|
+
|
|
121
|
+
Initializes all data feeds for rollover functionality.
|
|
122
|
+
"""
|
|
123
|
+
super().start()
|
|
124
|
+
# Loop through all data, prepare to start
|
|
125
|
+
for d in self._rolls:
|
|
126
|
+
d.setenvironment(self._env)
|
|
127
|
+
d._start()
|
|
128
|
+
|
|
129
|
+
# put the references in a separate list to have pops
|
|
130
|
+
self._ds = list(self._rolls)
|
|
131
|
+
# First data
|
|
132
|
+
self._d = self._ds.pop(0) if self._ds else None
|
|
133
|
+
# Expiration data
|
|
134
|
+
self._dexp = None
|
|
135
|
+
# Here defaults a minimum time, when comparing with any time, will move
|
|
136
|
+
self._dts = [datetime.min for xx in self._ds]
|
|
137
|
+
|
|
138
|
+
def stop(self):
|
|
139
|
+
"""Stop the RollOver data feed.
|
|
140
|
+
|
|
141
|
+
Stops all underlying data feeds.
|
|
142
|
+
"""
|
|
143
|
+
# End data
|
|
144
|
+
super().stop()
|
|
145
|
+
for d in self._rolls:
|
|
146
|
+
d.stop()
|
|
147
|
+
|
|
148
|
+
def _gettz(self):
|
|
149
|
+
# Get specific timezone
|
|
150
|
+
"""To be overriden by subclasses which may auto-calculate the
|
|
151
|
+
timezone"""
|
|
152
|
+
if self._rolls:
|
|
153
|
+
return self._rolls[0]._gettz()
|
|
154
|
+
return Localizer(self.p.tz)
|
|
155
|
+
|
|
156
|
+
def _checkdate(self, dt, d):
|
|
157
|
+
# Calculate if current rollover conditions are met
|
|
158
|
+
if self.p.checkdate is not None:
|
|
159
|
+
return self.p.checkdate(dt, d)
|
|
160
|
+
|
|
161
|
+
return False
|
|
162
|
+
|
|
163
|
+
def _checkcondition(self, d0, d1):
|
|
164
|
+
# Prepare to start rollover
|
|
165
|
+
if self.p.checkcondition is not None:
|
|
166
|
+
return self.p.checkcondition(d0, d1)
|
|
167
|
+
|
|
168
|
+
return True
|
|
169
|
+
|
|
170
|
+
def _load(self):
|
|
171
|
+
# Method to load data
|
|
172
|
+
while self._d is not None:
|
|
173
|
+
# When self._d is not None, call next
|
|
174
|
+
_next = self._d.next()
|
|
175
|
+
# If _next value is None, continue calling next
|
|
176
|
+
if _next is None: # no values yet, more will come
|
|
177
|
+
continue
|
|
178
|
+
# If _next value is False, current data switches to next data,
|
|
179
|
+
if _next is False: # no values from current data src
|
|
180
|
+
if self._ds:
|
|
181
|
+
self._d = self._ds.pop(0)
|
|
182
|
+
self._dts.pop(0)
|
|
183
|
+
else:
|
|
184
|
+
self._d = None
|
|
185
|
+
continue
|
|
186
|
+
# Current time of current data
|
|
187
|
+
dt0 = self._d.datetime.datetime() # current dt for active data
|
|
188
|
+
|
|
189
|
+
# Synchronize other datas using dt0
|
|
190
|
+
# Synchronize other data based on current time
|
|
191
|
+
for i, d_dt in enumerate(zip(self._ds, self._dts)):
|
|
192
|
+
d, dt = d_dt
|
|
193
|
+
# If other data's time is less than current time, move other data forward, increase time, and save time to self._dts
|
|
194
|
+
while dt < dt0:
|
|
195
|
+
if d.next() is None:
|
|
196
|
+
continue
|
|
197
|
+
self._dts[i] = dt = d.datetime.datetime()
|
|
198
|
+
|
|
199
|
+
# Move expired future as much as needed
|
|
200
|
+
# Move expired data
|
|
201
|
+
while self._dexp is not None:
|
|
202
|
+
if not self._dexp.next():
|
|
203
|
+
self._dexp = None
|
|
204
|
+
break
|
|
205
|
+
|
|
206
|
+
if self._dexp.datetime.datetime() < dt0:
|
|
207
|
+
continue
|
|
208
|
+
|
|
209
|
+
if self._dexp is None and self._checkdate(dt0, self._d):
|
|
210
|
+
# rule has been met ... check other factors only if 2 datas
|
|
211
|
+
# still there
|
|
212
|
+
if self._ds and self._checkcondition(self._d, self._ds[0]):
|
|
213
|
+
# Time to switch to next data
|
|
214
|
+
self._dexp = self._d
|
|
215
|
+
self._d = self._ds.pop(0)
|
|
216
|
+
self._dts.pop(0)
|
|
217
|
+
|
|
218
|
+
# Fill the line and tell we die
|
|
219
|
+
self.lines.datetime[0] = self._d.lines.datetime[0]
|
|
220
|
+
self.lines.open[0] = self._d.lines.open[0]
|
|
221
|
+
self.lines.high[0] = self._d.lines.high[0]
|
|
222
|
+
self.lines.low[0] = self._d.lines.low[0]
|
|
223
|
+
self.lines.close[0] = self._d.lines.close[0]
|
|
224
|
+
self.lines.volume[0] = self._d.lines.volume[0]
|
|
225
|
+
self.lines.openinterest[0] = self._d.lines.openinterest[0]
|
|
226
|
+
return True
|
|
227
|
+
|
|
228
|
+
# Out of the loop -> self._d is None, no data feed to return from
|
|
229
|
+
return False
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Sierra Chart CSV Data Feed Module - SierraChart CSV parsing.
|
|
3
|
+
|
|
4
|
+
This module provides the SierraChartCSVData feed for parsing
|
|
5
|
+
Sierra Chart exported CSV files.
|
|
6
|
+
|
|
7
|
+
Classes:
|
|
8
|
+
SierraChartCSVData: Parses SierraChart CSV format files.
|
|
9
|
+
|
|
10
|
+
Example:
|
|
11
|
+
>>> data = bt.feeds.SierraChartCSVData(dataname='sierra.csv')
|
|
12
|
+
>>> cerebro.adddata(data)
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from . import GenericCSVData
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# Read format with time format '%Y/%m/%d'
|
|
19
|
+
class SierraChartCSVData(GenericCSVData):
|
|
20
|
+
"""
|
|
21
|
+
Parses a `SierraChart <http://www.sierrachart.com>`_ CSV exported file.
|
|
22
|
+
|
|
23
|
+
Specific parameters (or specific meaning):
|
|
24
|
+
|
|
25
|
+
- ``dataname``: The filename to parse or a file-like object
|
|
26
|
+
|
|
27
|
+
- Uses GenericCSVData and simply modifies the dateformat (dtformat) to
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
params = (("dtformat", "%Y/%m/%d"),)
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Visual Chart Binary Data Feed Module - VisualChart binary files.
|
|
3
|
+
|
|
4
|
+
This module provides the VChartData feed for reading VisualChart
|
|
5
|
+
binary on-disk data files.
|
|
6
|
+
|
|
7
|
+
Classes:
|
|
8
|
+
VChartData: Reads VisualChart binary data files.
|
|
9
|
+
|
|
10
|
+
Example:
|
|
11
|
+
>>> data = bt.feeds.VChartData(dataname='data.fd')
|
|
12
|
+
>>> cerebro.adddata(data)
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import datetime
|
|
16
|
+
import os.path
|
|
17
|
+
import struct
|
|
18
|
+
|
|
19
|
+
from .. import feed
|
|
20
|
+
from ..dataseries import TimeFrame
|
|
21
|
+
from ..utils import date2num
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# Process Visual Chart binary data, supports daily or intraday data formats
|
|
25
|
+
class VChartData(feed.DataBase):
|
|
26
|
+
"""
|
|
27
|
+
Support for `Visual Chart <www.visualchart.com>`_ binary on-disk files for
|
|
28
|
+
both daily and intradaily formats.
|
|
29
|
+
|
|
30
|
+
Note:
|
|
31
|
+
|
|
32
|
+
- ``dataname``: to file or open file-like an object
|
|
33
|
+
|
|
34
|
+
If a file-like object is passed, the ``timeframe`` parameter will be
|
|
35
|
+
used to determine which is the actual timeframe.
|
|
36
|
+
|
|
37
|
+
Else the file extension (``.fd`` for daily and ``.min`` for intraday)
|
|
38
|
+
will be used.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
def __init__(self):
|
|
42
|
+
"""Initialize the VChart data feed."""
|
|
43
|
+
self.barfmt = None
|
|
44
|
+
self.f = None
|
|
45
|
+
self.barsize = None
|
|
46
|
+
self.dtsize = None
|
|
47
|
+
self.ext = None
|
|
48
|
+
|
|
49
|
+
def start(self):
|
|
50
|
+
"""Start the VChart data feed.
|
|
51
|
+
|
|
52
|
+
Opens the VisualChart binary file for reading.
|
|
53
|
+
"""
|
|
54
|
+
super().start()
|
|
55
|
+
|
|
56
|
+
# Not yet known if an extension is needed
|
|
57
|
+
self.ext = ""
|
|
58
|
+
|
|
59
|
+
if not hasattr(self.p.dataname, "read"):
|
|
60
|
+
# assume is a string because it has no write method
|
|
61
|
+
|
|
62
|
+
if self.p.dataname.endswith(".fd"):
|
|
63
|
+
self.p.timeframe = TimeFrame.Days
|
|
64
|
+
elif self.p.dataname.endswith(".min"):
|
|
65
|
+
self.p.timeframe = TimeFrame.Minutes
|
|
66
|
+
else:
|
|
67
|
+
# Neither fd nor min ... just the code, assign extension
|
|
68
|
+
if self.p.timeframe == TimeFrame.Days:
|
|
69
|
+
self.ext = ".fd"
|
|
70
|
+
else:
|
|
71
|
+
self.ext = ".min"
|
|
72
|
+
|
|
73
|
+
if self.p.timeframe >= TimeFrame.Days:
|
|
74
|
+
self.barsize = 28
|
|
75
|
+
self.dtsize = 1
|
|
76
|
+
self.barfmt = "IffffII"
|
|
77
|
+
else:
|
|
78
|
+
self.dtsize = 2
|
|
79
|
+
self.barsize = 32
|
|
80
|
+
self.barfmt = "IIffffII"
|
|
81
|
+
|
|
82
|
+
self.f = None
|
|
83
|
+
if hasattr(self.p.dataname, "read"):
|
|
84
|
+
# A file has been passed in (ex: from a GUI)
|
|
85
|
+
self.f = self.p.dataname
|
|
86
|
+
else:
|
|
87
|
+
dataname = self.p.dataname + self.ext
|
|
88
|
+
# Let an exception propagate
|
|
89
|
+
self.f = open(dataname, "rb")
|
|
90
|
+
|
|
91
|
+
def stop(self):
|
|
92
|
+
"""Stop the VChart data feed.
|
|
93
|
+
|
|
94
|
+
Closes the open file handle.
|
|
95
|
+
"""
|
|
96
|
+
if self.f is not None:
|
|
97
|
+
self.f.close()
|
|
98
|
+
self.f = None
|
|
99
|
+
|
|
100
|
+
def _load(self):
|
|
101
|
+
if self.f is None:
|
|
102
|
+
return False
|
|
103
|
+
|
|
104
|
+
# Let an exception propagate to let the caller know
|
|
105
|
+
bardata = self.f.read(self.barsize)
|
|
106
|
+
if not bardata:
|
|
107
|
+
return False
|
|
108
|
+
|
|
109
|
+
bdata = struct.unpack(self.barfmt, bardata)
|
|
110
|
+
|
|
111
|
+
# Years are stored as if they had 500 days
|
|
112
|
+
y, md = divmod(bdata[0], 500)
|
|
113
|
+
# Months are stored as if they had 32 days
|
|
114
|
+
m, d = divmod(md, 32)
|
|
115
|
+
dt = datetime.datetime(y, m, d)
|
|
116
|
+
|
|
117
|
+
if self.dtsize > 1: # Minute Bars
|
|
118
|
+
# Daily Time is stored in seconds
|
|
119
|
+
hhmm, ss = divmod(bdata[1], 60)
|
|
120
|
+
hh, mm = divmod(hhmm, 60)
|
|
121
|
+
dt = dt.replace(hour=hh, minute=mm, second=ss)
|
|
122
|
+
|
|
123
|
+
self.lines.datetime[0] = date2num(dt)
|
|
124
|
+
|
|
125
|
+
o, h, low, c, v, oi = bdata[self.dtsize :]
|
|
126
|
+
self.lines.open[0] = o
|
|
127
|
+
self.lines.high[0] = h
|
|
128
|
+
self.lines.low[0] = low
|
|
129
|
+
self.lines.close[0] = c
|
|
130
|
+
self.lines.volume[0] = v
|
|
131
|
+
self.lines.openinterest[0] = oi
|
|
132
|
+
|
|
133
|
+
return True
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class VChartFeed(feed.FeedBase):
|
|
137
|
+
"""VisualChart feed class.
|
|
138
|
+
|
|
139
|
+
Wrapper class for VChartData feed functionality.
|
|
140
|
+
"""
|
|
141
|
+
|
|
142
|
+
DataCls = VChartData
|
|
143
|
+
|
|
144
|
+
params = (("basepath", ""),) + DataCls.params._gettuple()
|
|
145
|
+
|
|
146
|
+
def _getdata(self, dataname, **kwargs):
|
|
147
|
+
maincode = dataname[0:2]
|
|
148
|
+
subcode = dataname[2:6]
|
|
149
|
+
|
|
150
|
+
datapath = os.path.join(
|
|
151
|
+
self.p.basepath,
|
|
152
|
+
"RealServer",
|
|
153
|
+
"Data",
|
|
154
|
+
maincode,
|
|
155
|
+
subcode,
|
|
156
|
+
dataname, # 01 00XX
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
newkwargs = self.p._getkwargs()
|
|
160
|
+
newkwargs.update(kwargs)
|
|
161
|
+
kwargs["dataname"] = datapath
|
|
162
|
+
return self.DataCls(**kwargs)
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""VisualChart CSV Data Feed Module - VisualChart CSV parsing.
|
|
3
|
+
|
|
4
|
+
This module provides the VChartCSVData feed for parsing VisualChart
|
|
5
|
+
CSV exported files.
|
|
6
|
+
|
|
7
|
+
Classes:
|
|
8
|
+
VChartCSVData: Parses VisualChart CSV format files.
|
|
9
|
+
|
|
10
|
+
Example:
|
|
11
|
+
>>> data = bt.feeds.VChartCSVData(dataname='vchart.csv')
|
|
12
|
+
>>> cerebro.adddata(data)
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import datetime
|
|
16
|
+
|
|
17
|
+
from .. import feed
|
|
18
|
+
from ..dataseries import TimeFrame
|
|
19
|
+
from ..utils import date2num
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# Process Visual Chart CSV files
|
|
23
|
+
class VChartCSVData(feed.CSVDataBase):
|
|
24
|
+
"""
|
|
25
|
+
Parses a `VisualChart <http://www.visualchart.com>`_ CSV exported file.
|
|
26
|
+
|
|
27
|
+
Specific parameters (or specific meaning):
|
|
28
|
+
|
|
29
|
+
- ``dataname``: The filename to parse or a file-like object
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
vctframes = {
|
|
33
|
+
"I": TimeFrame.Minutes,
|
|
34
|
+
"D": TimeFrame.Days,
|
|
35
|
+
"W": TimeFrame.Weeks,
|
|
36
|
+
"M": TimeFrame.Months,
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
def _loadline(self, linetokens):
|
|
40
|
+
itokens = iter(linetokens)
|
|
41
|
+
|
|
42
|
+
ticker = next(itokens) # skip ticker name
|
|
43
|
+
if not self._name:
|
|
44
|
+
self._name = ticker
|
|
45
|
+
|
|
46
|
+
# day/intraday indication
|
|
47
|
+
timeframe = next(itokens)
|
|
48
|
+
|
|
49
|
+
self._timeframe = self.vctframes[timeframe]
|
|
50
|
+
|
|
51
|
+
dttxt = next(itokens)
|
|
52
|
+
y, m, d = int(dttxt[0:4]), int(dttxt[4:6]), int(dttxt[6:8])
|
|
53
|
+
|
|
54
|
+
tmtxt = next(itokens)
|
|
55
|
+
if timeframe == "I":
|
|
56
|
+
# use the provided time
|
|
57
|
+
hh, mmss = divmod(int(tmtxt), 10000)
|
|
58
|
+
mm, ss = divmod(mmss, 100)
|
|
59
|
+
else:
|
|
60
|
+
# put it at the end of the session parameter
|
|
61
|
+
hh = self.p.sessionend.hour
|
|
62
|
+
mm = self.p.sessionend.minute
|
|
63
|
+
ss = self.p.sessionend.second
|
|
64
|
+
|
|
65
|
+
dtnum = date2num(datetime.datetime(y, m, d, hh, mm, ss))
|
|
66
|
+
|
|
67
|
+
self.lines.datetime[0] = dtnum
|
|
68
|
+
self.lines.open[0] = float(next(itokens))
|
|
69
|
+
self.lines.high[0] = float(next(itokens))
|
|
70
|
+
self.lines.low[0] = float(next(itokens))
|
|
71
|
+
self.lines.close[0] = float(next(itokens))
|
|
72
|
+
self.lines.volume[0] = float(next(itokens))
|
|
73
|
+
self.lines.openinterest[0] = float(next(itokens))
|
|
74
|
+
|
|
75
|
+
return True
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class VChartCSV(feed.CSVFeedBase):
|
|
79
|
+
"""VisualChart CSV feed class.
|
|
80
|
+
|
|
81
|
+
Wrapper class for VChartCSVData feed functionality.
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
DataCls = VChartCSVData
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""VChartFile Data Feed Module - VisualChart file interface.
|
|
3
|
+
|
|
4
|
+
This module provides the VChartFile feed for reading VisualChart
|
|
5
|
+
binary on-disk files using market codes.
|
|
6
|
+
|
|
7
|
+
Classes:
|
|
8
|
+
VChartFile: VisualChart binary file feed by market code.
|
|
9
|
+
|
|
10
|
+
Example:
|
|
11
|
+
>>> data = bt.feeds.VChartFile(dataname='015ES')
|
|
12
|
+
>>> cerebro.adddata(data)
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import os.path
|
|
16
|
+
from datetime import datetime
|
|
17
|
+
from struct import unpack
|
|
18
|
+
|
|
19
|
+
from .. import stores
|
|
20
|
+
from ..dataseries import TimeFrame
|
|
21
|
+
from ..feed import DataBase
|
|
22
|
+
from ..utils import date2num # avoid dict lookups
|
|
23
|
+
from ..utils.log_message import get_logger
|
|
24
|
+
|
|
25
|
+
logger = get_logger(__name__)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class VChartFile(DataBase):
|
|
29
|
+
"""
|
|
30
|
+
Support for `Visual Chart <www.visualchart.com>`_ binary on-disk files for
|
|
31
|
+
both daily and intradaily formats.
|
|
32
|
+
|
|
33
|
+
Note:
|
|
34
|
+
|
|
35
|
+
- ``dataname``: Market code displayed by Visual Chart. Example: 015ES for
|
|
36
|
+
EuroStoxx 50 continuous future
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def __init__(self, **kwargs):
|
|
40
|
+
"""Initialize the VChartFile data feed.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
**kwargs: Keyword arguments for data feed configuration.
|
|
44
|
+
"""
|
|
45
|
+
super().__init__(**kwargs)
|
|
46
|
+
# Handle original metaclass registration functionality
|
|
47
|
+
if hasattr(stores, "VChartFile"):
|
|
48
|
+
stores.VChartFile.DataCls = self.__class__
|
|
49
|
+
|
|
50
|
+
self.f = None
|
|
51
|
+
self._barfmt = None
|
|
52
|
+
self._dtsize = None
|
|
53
|
+
self._barsize = None
|
|
54
|
+
self._store = None
|
|
55
|
+
|
|
56
|
+
def start(self):
|
|
57
|
+
"""Start the VChartFile data feed.
|
|
58
|
+
|
|
59
|
+
Opens the VisualChart binary file for reading.
|
|
60
|
+
"""
|
|
61
|
+
super().start()
|
|
62
|
+
if self._store is None:
|
|
63
|
+
self._store = stores.VChartFile()
|
|
64
|
+
self._store.start()
|
|
65
|
+
|
|
66
|
+
self._store.start(data=self)
|
|
67
|
+
|
|
68
|
+
# Choose extension and extraction/calculation parameters
|
|
69
|
+
if self.p.timeframe < TimeFrame.Minutes:
|
|
70
|
+
ext = ".tck" # seconds will still need resampling
|
|
71
|
+
# FIXME: find reference to tick counter for format
|
|
72
|
+
elif self.p.timeframe < TimeFrame.Days:
|
|
73
|
+
ext = ".min"
|
|
74
|
+
self._dtsize = 2
|
|
75
|
+
self._barsize = 32
|
|
76
|
+
self._barfmt = "IIffffII"
|
|
77
|
+
else:
|
|
78
|
+
ext = ".fd"
|
|
79
|
+
self._barsize = 28
|
|
80
|
+
self._dtsize = 1
|
|
81
|
+
self._barfmt = "IffffII"
|
|
82
|
+
|
|
83
|
+
# Construct a full path
|
|
84
|
+
basepath = self._store.get_datapath()
|
|
85
|
+
|
|
86
|
+
# Example: 01 + 0 + 015ES + .fd -> 010015ES.fd
|
|
87
|
+
dataname = "01" + "0" + self.p.dataname + ext
|
|
88
|
+
# 015ES -> 0 + 015 -> 0015
|
|
89
|
+
mktcode = "0" + self.p.dataname[0:3]
|
|
90
|
+
|
|
91
|
+
# basepath/0015/010015ES.fd
|
|
92
|
+
path = os.path.join(basepath, mktcode, dataname)
|
|
93
|
+
try:
|
|
94
|
+
self.f = open(path, "rb")
|
|
95
|
+
except OSError:
|
|
96
|
+
self.f = None
|
|
97
|
+
|
|
98
|
+
def stop(self):
|
|
99
|
+
"""Stop the VChartFile data feed.
|
|
100
|
+
|
|
101
|
+
Closes the open file handle.
|
|
102
|
+
"""
|
|
103
|
+
if self.f is not None:
|
|
104
|
+
self.f.close()
|
|
105
|
+
self.f = None
|
|
106
|
+
|
|
107
|
+
def _load(self):
|
|
108
|
+
if self.f is None:
|
|
109
|
+
return False # cannot load more
|
|
110
|
+
|
|
111
|
+
try:
|
|
112
|
+
bardata = self.f.read(self._barsize)
|
|
113
|
+
except OSError:
|
|
114
|
+
self.f = None # cannot return, nullify file
|
|
115
|
+
return False # cannot load more
|
|
116
|
+
|
|
117
|
+
if not bardata or len(bardata) < self._barsize:
|
|
118
|
+
self.f = None # cannot return, nullify file
|
|
119
|
+
return False # cannot load more
|
|
120
|
+
|
|
121
|
+
try:
|
|
122
|
+
bdata = unpack(self._barfmt, bardata)
|
|
123
|
+
except Exception as e:
|
|
124
|
+
logger.warning("vchart bar unpack failed, stopping feed: %s", e)
|
|
125
|
+
self.f = None
|
|
126
|
+
return False
|
|
127
|
+
|
|
128
|
+
# First Date
|
|
129
|
+
y, md = divmod(bdata[0], 500) # Years stored as if they had 500 days
|
|
130
|
+
m, d = divmod(md, 32) # Months stored as if they had 32 days
|
|
131
|
+
dt = datetime(y, m, d)
|
|
132
|
+
|
|
133
|
+
# Time
|
|
134
|
+
if self._dtsize > 1: # Minute Bars
|
|
135
|
+
# Daily Time is stored in seconds
|
|
136
|
+
hhmm, ss = divmod(bdata[1], 60)
|
|
137
|
+
hh, mm = divmod(hhmm, 60)
|
|
138
|
+
dt = dt.replace(hour=hh, minute=mm, second=ss)
|
|
139
|
+
else: # Daily Bars
|
|
140
|
+
dt = datetime.combine(dt, self.p.sessionend)
|
|
141
|
+
|
|
142
|
+
self.lines.datetime[0] = date2num(dt) # Store time
|
|
143
|
+
|
|
144
|
+
# Get the rest of the fields
|
|
145
|
+
o, h, low, c, v, oi = bdata[self._dtsize :]
|
|
146
|
+
self.lines.open[0] = o
|
|
147
|
+
self.lines.high[0] = h
|
|
148
|
+
self.lines.low[0] = low
|
|
149
|
+
self.lines.close[0] = c
|
|
150
|
+
self.lines.volume[0] = v
|
|
151
|
+
self.lines.openinterest[0] = oi
|
|
152
|
+
|
|
153
|
+
return True # a bar has been successfully loaded
|