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
backtrader/events.py
ADDED
|
@@ -0,0 +1,980 @@
|
|
|
1
|
+
"""Unified event data structures for tick-level backtesting and live trading.
|
|
2
|
+
|
|
3
|
+
This module defines the base EventData class and concrete event types used
|
|
4
|
+
across all data channels. Events use Python dataclasses for performance
|
|
5
|
+
and type safety.
|
|
6
|
+
|
|
7
|
+
Event Types:
|
|
8
|
+
- TickEvent: Individual trade/tick data
|
|
9
|
+
- OrderBookSnapshot: Order book depth snapshot
|
|
10
|
+
- FundingEvent: Funding rate data for perpetual contracts
|
|
11
|
+
- BarEvent: OHLCV bar data
|
|
12
|
+
|
|
13
|
+
Example:
|
|
14
|
+
Creating a tick event::
|
|
15
|
+
|
|
16
|
+
tick = TickEvent(
|
|
17
|
+
timestamp=1609459200.123,
|
|
18
|
+
symbol='BTC/USDT',
|
|
19
|
+
price=50000.5,
|
|
20
|
+
volume=1.234,
|
|
21
|
+
direction='buy'
|
|
22
|
+
)
|
|
23
|
+
assert tick.validate()
|
|
24
|
+
assert tick.event_type == 'tick'
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
import os
|
|
28
|
+
import time
|
|
29
|
+
import uuid
|
|
30
|
+
from abc import ABC, abstractmethod
|
|
31
|
+
from dataclasses import asdict, dataclass, field
|
|
32
|
+
from typing import List, Optional, Tuple
|
|
33
|
+
|
|
34
|
+
_CLOCK_DOMAIN_ID = f"process-{os.getpid()}-{uuid.uuid4().hex}"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _event_id() -> str:
|
|
38
|
+
"""Return an opaque process-local identity for causal event accounting."""
|
|
39
|
+
return uuid.uuid4().hex
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@dataclass
|
|
43
|
+
class EventData(ABC):
|
|
44
|
+
"""Base class for all event data.
|
|
45
|
+
|
|
46
|
+
All event types share common fields: timestamp, symbol, exchange,
|
|
47
|
+
asset_type, and local_time. Subclasses must implement event_type
|
|
48
|
+
property and can override validate() for type-specific checks.
|
|
49
|
+
|
|
50
|
+
Attributes:
|
|
51
|
+
timestamp: Unix timestamp in seconds (supports millisecond precision).
|
|
52
|
+
symbol: Trading pair symbol (e.g., 'BTC/USDT').
|
|
53
|
+
exchange: Exchange name (e.g., 'binance').
|
|
54
|
+
asset_type: Asset type ('spot', 'swap', 'futures').
|
|
55
|
+
local_time: Local receive timestamp (for latency tracking).
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
timestamp: float
|
|
59
|
+
symbol: str
|
|
60
|
+
exchange: str = ""
|
|
61
|
+
asset_type: str = "spot"
|
|
62
|
+
local_time: Optional[float] = None
|
|
63
|
+
exchange_time: Optional[float] = None
|
|
64
|
+
received_wall_time: Optional[float] = None
|
|
65
|
+
received_monotonic_ns: Optional[int] = None
|
|
66
|
+
clock_domain_id: str = _CLOCK_DOMAIN_ID
|
|
67
|
+
sequence: int = 0
|
|
68
|
+
previous_sequence: Optional[int] = None
|
|
69
|
+
snapshot_or_delta: str = ""
|
|
70
|
+
continuity_status: str = "unknown"
|
|
71
|
+
stale: bool = False
|
|
72
|
+
stale_reason: str = ""
|
|
73
|
+
source: str = ""
|
|
74
|
+
event_id: str = field(default_factory=_event_id)
|
|
75
|
+
coalesced_count: int = 1
|
|
76
|
+
|
|
77
|
+
def __post_init__(self) -> None:
|
|
78
|
+
"""Fill receive-clock metadata without confusing it with exchange time."""
|
|
79
|
+
if self.exchange_time is None:
|
|
80
|
+
self.exchange_time = self.timestamp
|
|
81
|
+
if self.received_wall_time is None:
|
|
82
|
+
self.received_wall_time = self.local_time or time.time()
|
|
83
|
+
if self.received_monotonic_ns is None:
|
|
84
|
+
self.received_monotonic_ns = time.monotonic_ns()
|
|
85
|
+
if not self.clock_domain_id:
|
|
86
|
+
self.clock_domain_id = _CLOCK_DOMAIN_ID
|
|
87
|
+
if not self.event_id:
|
|
88
|
+
self.event_id = _event_id()
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
def continuity(self) -> str:
|
|
92
|
+
"""Compatibility alias for the canonical continuity status."""
|
|
93
|
+
return self.continuity_status
|
|
94
|
+
|
|
95
|
+
@property
|
|
96
|
+
@abstractmethod
|
|
97
|
+
def event_type(self) -> str:
|
|
98
|
+
"""Return the event type identifier string."""
|
|
99
|
+
|
|
100
|
+
def to_dict(self) -> dict:
|
|
101
|
+
"""Convert event data to a dictionary for serialization."""
|
|
102
|
+
result = asdict(self)
|
|
103
|
+
result["continuity"] = self.continuity_status
|
|
104
|
+
# Include dynamically-set attributes (e.g. datetime set by btapifeed)
|
|
105
|
+
if hasattr(self, "datetime") and "datetime" not in result:
|
|
106
|
+
result["datetime"] = getattr(self, "datetime")
|
|
107
|
+
return result
|
|
108
|
+
|
|
109
|
+
def validate(self) -> bool:
|
|
110
|
+
"""Validate common event fields.
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
True if valid, False otherwise.
|
|
114
|
+
"""
|
|
115
|
+
if not isinstance(self.timestamp, (int, float)) or self.timestamp <= 0:
|
|
116
|
+
return False
|
|
117
|
+
if not isinstance(self.symbol, str) or not self.symbol:
|
|
118
|
+
return False
|
|
119
|
+
if self.local_time is not None:
|
|
120
|
+
if not isinstance(self.local_time, (int, float)) or self.local_time <= 0:
|
|
121
|
+
return False
|
|
122
|
+
if self.exchange_time is not None and (
|
|
123
|
+
not isinstance(self.exchange_time, (int, float)) or self.exchange_time <= 0
|
|
124
|
+
):
|
|
125
|
+
return False
|
|
126
|
+
if self.received_wall_time is not None and (
|
|
127
|
+
not isinstance(self.received_wall_time, (int, float)) or self.received_wall_time <= 0
|
|
128
|
+
):
|
|
129
|
+
return False
|
|
130
|
+
if self.received_monotonic_ns is not None and (
|
|
131
|
+
not isinstance(self.received_monotonic_ns, int) or self.received_monotonic_ns <= 0
|
|
132
|
+
):
|
|
133
|
+
return False
|
|
134
|
+
if not isinstance(self.coalesced_count, int) or self.coalesced_count < 1:
|
|
135
|
+
return False
|
|
136
|
+
if self.stale and not self.stale_reason:
|
|
137
|
+
return False
|
|
138
|
+
return True
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
@dataclass(init=False)
|
|
142
|
+
class TickEvent(EventData):
|
|
143
|
+
"""Tick/trade event data.
|
|
144
|
+
|
|
145
|
+
Represents a single trade execution on an exchange. Compatible with
|
|
146
|
+
the existing TickerData interface via adapter pattern.
|
|
147
|
+
|
|
148
|
+
Attributes:
|
|
149
|
+
price: Trade execution price.
|
|
150
|
+
volume: Trade execution volume/amount.
|
|
151
|
+
direction: Trade direction ('buy' or 'sell').
|
|
152
|
+
trade_id: Exchange trade identifier.
|
|
153
|
+
bid_price: Best bid price at time of trade.
|
|
154
|
+
ask_price: Best ask price at time of trade.
|
|
155
|
+
bid_volume: Best bid volume at time of trade.
|
|
156
|
+
ask_volume: Best ask volume at time of trade.
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
price: float = 0.0
|
|
160
|
+
volume: float = 0.0
|
|
161
|
+
direction: str = "buy"
|
|
162
|
+
trade_id: str = ""
|
|
163
|
+
bid_price: Optional[float] = None
|
|
164
|
+
ask_price: Optional[float] = None
|
|
165
|
+
bid_volume: Optional[float] = None
|
|
166
|
+
ask_volume: Optional[float] = None
|
|
167
|
+
|
|
168
|
+
def __init__(
|
|
169
|
+
self,
|
|
170
|
+
timestamp: float,
|
|
171
|
+
symbol: str,
|
|
172
|
+
exchange: str = "",
|
|
173
|
+
asset_type: str = "spot",
|
|
174
|
+
local_time: Optional[float] = None,
|
|
175
|
+
price: float = 0.0,
|
|
176
|
+
volume: float = 0.0,
|
|
177
|
+
direction: str = "buy",
|
|
178
|
+
trade_id: str = "",
|
|
179
|
+
bid_price: Optional[float] = None,
|
|
180
|
+
ask_price: Optional[float] = None,
|
|
181
|
+
bid_volume: Optional[float] = None,
|
|
182
|
+
ask_volume: Optional[float] = None,
|
|
183
|
+
*,
|
|
184
|
+
exchange_time: Optional[float] = None,
|
|
185
|
+
received_wall_time: Optional[float] = None,
|
|
186
|
+
received_monotonic_ns: Optional[int] = None,
|
|
187
|
+
clock_domain_id: str = _CLOCK_DOMAIN_ID,
|
|
188
|
+
sequence: int = 0,
|
|
189
|
+
previous_sequence: Optional[int] = None,
|
|
190
|
+
snapshot_or_delta: str = "",
|
|
191
|
+
continuity_status: str = "unknown",
|
|
192
|
+
stale: bool = False,
|
|
193
|
+
stale_reason: str = "",
|
|
194
|
+
source: str = "",
|
|
195
|
+
event_id: Optional[str] = None,
|
|
196
|
+
coalesced_count: int = 1,
|
|
197
|
+
) -> None:
|
|
198
|
+
EventData.__init__(
|
|
199
|
+
self,
|
|
200
|
+
timestamp,
|
|
201
|
+
symbol,
|
|
202
|
+
exchange,
|
|
203
|
+
asset_type,
|
|
204
|
+
local_time,
|
|
205
|
+
exchange_time,
|
|
206
|
+
received_wall_time,
|
|
207
|
+
received_monotonic_ns,
|
|
208
|
+
clock_domain_id,
|
|
209
|
+
sequence,
|
|
210
|
+
previous_sequence,
|
|
211
|
+
snapshot_or_delta,
|
|
212
|
+
continuity_status,
|
|
213
|
+
stale,
|
|
214
|
+
stale_reason,
|
|
215
|
+
source,
|
|
216
|
+
event_id or _event_id(),
|
|
217
|
+
coalesced_count,
|
|
218
|
+
)
|
|
219
|
+
self.price = price
|
|
220
|
+
self.volume = volume
|
|
221
|
+
self.direction = direction
|
|
222
|
+
self.trade_id = trade_id
|
|
223
|
+
self.bid_price = bid_price
|
|
224
|
+
self.ask_price = ask_price
|
|
225
|
+
self.bid_volume = bid_volume
|
|
226
|
+
self.ask_volume = ask_volume
|
|
227
|
+
|
|
228
|
+
@property
|
|
229
|
+
def event_type(self) -> str:
|
|
230
|
+
"""Return the event type identifier.
|
|
231
|
+
|
|
232
|
+
Returns:
|
|
233
|
+
str: The string 'tick' for tick events.
|
|
234
|
+
"""
|
|
235
|
+
return "tick"
|
|
236
|
+
|
|
237
|
+
def validate(self) -> bool:
|
|
238
|
+
"""Validate tick-specific fields.
|
|
239
|
+
|
|
240
|
+
Checks:
|
|
241
|
+
- Common fields valid (via super)
|
|
242
|
+
- Price > 0
|
|
243
|
+
- Volume >= 0
|
|
244
|
+
- Direction is 'buy' or 'sell'
|
|
245
|
+
- Optional bid/ask prices > 0 if present
|
|
246
|
+
"""
|
|
247
|
+
if not super().validate():
|
|
248
|
+
return False
|
|
249
|
+
if not isinstance(self.price, (int, float)) or self.price <= 0:
|
|
250
|
+
return False
|
|
251
|
+
if not isinstance(self.volume, (int, float)) or self.volume < 0:
|
|
252
|
+
return False
|
|
253
|
+
if self.direction not in ("buy", "sell"):
|
|
254
|
+
return False
|
|
255
|
+
if self.bid_price is not None and self.bid_price <= 0:
|
|
256
|
+
return False
|
|
257
|
+
if self.ask_price is not None and self.ask_price <= 0:
|
|
258
|
+
return False
|
|
259
|
+
if self.bid_volume is not None and self.bid_volume < 0:
|
|
260
|
+
return False
|
|
261
|
+
if self.ask_volume is not None and self.ask_volume < 0:
|
|
262
|
+
return False
|
|
263
|
+
return True
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
@dataclass(init=False)
|
|
267
|
+
class OrderBookSnapshot(EventData):
|
|
268
|
+
"""Order book depth snapshot.
|
|
269
|
+
|
|
270
|
+
Stores bid/ask depth levels as lists of (price, quantity) tuples.
|
|
271
|
+
Bids are in descending price order, asks in ascending price order.
|
|
272
|
+
|
|
273
|
+
Attributes:
|
|
274
|
+
bids: List of (price, quantity) tuples, descending by price.
|
|
275
|
+
asks: List of (price, quantity) tuples, ascending by price.
|
|
276
|
+
"""
|
|
277
|
+
|
|
278
|
+
bids: List[Tuple[float, float]] = field(default_factory=list)
|
|
279
|
+
asks: List[Tuple[float, float]] = field(default_factory=list)
|
|
280
|
+
|
|
281
|
+
def __init__(
|
|
282
|
+
self,
|
|
283
|
+
timestamp: float,
|
|
284
|
+
symbol: str,
|
|
285
|
+
exchange: str = "",
|
|
286
|
+
asset_type: str = "spot",
|
|
287
|
+
local_time: Optional[float] = None,
|
|
288
|
+
bids: Optional[List[Tuple[float, float]]] = None,
|
|
289
|
+
asks: Optional[List[Tuple[float, float]]] = None,
|
|
290
|
+
*,
|
|
291
|
+
exchange_time: Optional[float] = None,
|
|
292
|
+
received_wall_time: Optional[float] = None,
|
|
293
|
+
received_monotonic_ns: Optional[int] = None,
|
|
294
|
+
clock_domain_id: str = _CLOCK_DOMAIN_ID,
|
|
295
|
+
sequence: int = 0,
|
|
296
|
+
previous_sequence: Optional[int] = None,
|
|
297
|
+
snapshot_or_delta: str = "",
|
|
298
|
+
continuity_status: str = "unknown",
|
|
299
|
+
stale: bool = False,
|
|
300
|
+
stale_reason: str = "",
|
|
301
|
+
source: str = "",
|
|
302
|
+
event_id: Optional[str] = None,
|
|
303
|
+
coalesced_count: int = 1,
|
|
304
|
+
) -> None:
|
|
305
|
+
EventData.__init__(
|
|
306
|
+
self,
|
|
307
|
+
timestamp,
|
|
308
|
+
symbol,
|
|
309
|
+
exchange,
|
|
310
|
+
asset_type,
|
|
311
|
+
local_time,
|
|
312
|
+
exchange_time,
|
|
313
|
+
received_wall_time,
|
|
314
|
+
received_monotonic_ns,
|
|
315
|
+
clock_domain_id,
|
|
316
|
+
sequence,
|
|
317
|
+
previous_sequence,
|
|
318
|
+
snapshot_or_delta,
|
|
319
|
+
continuity_status,
|
|
320
|
+
stale,
|
|
321
|
+
stale_reason,
|
|
322
|
+
source,
|
|
323
|
+
event_id or _event_id(),
|
|
324
|
+
coalesced_count,
|
|
325
|
+
)
|
|
326
|
+
self.bids = list(bids or ())
|
|
327
|
+
self.asks = list(asks or ())
|
|
328
|
+
|
|
329
|
+
@property
|
|
330
|
+
def event_type(self) -> str:
|
|
331
|
+
"""Return the event type identifier.
|
|
332
|
+
|
|
333
|
+
Returns:
|
|
334
|
+
str: The string 'orderbook' for order book snapshot events.
|
|
335
|
+
"""
|
|
336
|
+
return "orderbook"
|
|
337
|
+
|
|
338
|
+
@property
|
|
339
|
+
def best_bid(self) -> Optional[float]:
|
|
340
|
+
"""Best (highest) bid price."""
|
|
341
|
+
return self.bids[0][0] if self.bids else None
|
|
342
|
+
|
|
343
|
+
@property
|
|
344
|
+
def best_ask(self) -> Optional[float]:
|
|
345
|
+
"""Best (lowest) ask price."""
|
|
346
|
+
return self.asks[0][0] if self.asks else None
|
|
347
|
+
|
|
348
|
+
@property
|
|
349
|
+
def spread(self) -> Optional[float]:
|
|
350
|
+
"""Spread between best ask and best bid."""
|
|
351
|
+
if self.best_bid is not None and self.best_ask is not None:
|
|
352
|
+
return self.best_ask - self.best_bid
|
|
353
|
+
return None
|
|
354
|
+
|
|
355
|
+
@property
|
|
356
|
+
def mid_price(self) -> Optional[float]:
|
|
357
|
+
"""Mid price between best bid and best ask."""
|
|
358
|
+
if self.best_bid is not None and self.best_ask is not None:
|
|
359
|
+
return (self.best_bid + self.best_ask) / 2.0
|
|
360
|
+
return None
|
|
361
|
+
|
|
362
|
+
def validate(self) -> bool:
|
|
363
|
+
"""Validate order book specific fields.
|
|
364
|
+
|
|
365
|
+
Checks:
|
|
366
|
+
- Common fields valid (via super)
|
|
367
|
+
- At least one bid and one ask level
|
|
368
|
+
- Bids in descending order
|
|
369
|
+
- Asks in ascending order
|
|
370
|
+
- Best ask > best bid (positive spread)
|
|
371
|
+
- All prices > 0 and quantities > 0
|
|
372
|
+
"""
|
|
373
|
+
if not super().validate():
|
|
374
|
+
return False
|
|
375
|
+
if not self.bids or not self.asks:
|
|
376
|
+
return False
|
|
377
|
+
# Validate bid levels: descending order, positive values
|
|
378
|
+
for i, (price, qty) in enumerate(self.bids):
|
|
379
|
+
if price <= 0 or qty <= 0:
|
|
380
|
+
return False
|
|
381
|
+
if i > 0 and price > self.bids[i - 1][0]:
|
|
382
|
+
return False
|
|
383
|
+
# Validate ask levels: ascending order, positive values
|
|
384
|
+
for i, (price, qty) in enumerate(self.asks):
|
|
385
|
+
if price <= 0 or qty <= 0:
|
|
386
|
+
return False
|
|
387
|
+
if i > 0 and price < self.asks[i - 1][0]:
|
|
388
|
+
return False
|
|
389
|
+
# Spread check: best ask must be greater than best bid
|
|
390
|
+
if self.bids[0][0] >= self.asks[0][0]:
|
|
391
|
+
return False
|
|
392
|
+
return True
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
@dataclass(init=False)
|
|
396
|
+
class FundingEvent(EventData):
|
|
397
|
+
"""Funding rate event for perpetual contracts.
|
|
398
|
+
|
|
399
|
+
Attributes:
|
|
400
|
+
rate: Current funding rate.
|
|
401
|
+
mark_price: Current mark price.
|
|
402
|
+
next_funding_time: Timestamp of next funding settlement.
|
|
403
|
+
predicted_rate: Predicted next funding rate.
|
|
404
|
+
"""
|
|
405
|
+
|
|
406
|
+
rate: float = 0.0
|
|
407
|
+
mark_price: float = 0.0
|
|
408
|
+
next_funding_time: float = 0.0
|
|
409
|
+
predicted_rate: float = 0.0
|
|
410
|
+
|
|
411
|
+
def __init__(
|
|
412
|
+
self,
|
|
413
|
+
timestamp: float,
|
|
414
|
+
symbol: str,
|
|
415
|
+
exchange: str = "",
|
|
416
|
+
asset_type: str = "spot",
|
|
417
|
+
local_time: Optional[float] = None,
|
|
418
|
+
rate: float = 0.0,
|
|
419
|
+
mark_price: float = 0.0,
|
|
420
|
+
next_funding_time: float = 0.0,
|
|
421
|
+
predicted_rate: float = 0.0,
|
|
422
|
+
*,
|
|
423
|
+
exchange_time: Optional[float] = None,
|
|
424
|
+
received_wall_time: Optional[float] = None,
|
|
425
|
+
received_monotonic_ns: Optional[int] = None,
|
|
426
|
+
clock_domain_id: str = _CLOCK_DOMAIN_ID,
|
|
427
|
+
sequence: int = 0,
|
|
428
|
+
previous_sequence: Optional[int] = None,
|
|
429
|
+
snapshot_or_delta: str = "",
|
|
430
|
+
continuity_status: str = "unknown",
|
|
431
|
+
stale: bool = False,
|
|
432
|
+
stale_reason: str = "",
|
|
433
|
+
source: str = "",
|
|
434
|
+
event_id: Optional[str] = None,
|
|
435
|
+
coalesced_count: int = 1,
|
|
436
|
+
) -> None:
|
|
437
|
+
EventData.__init__(
|
|
438
|
+
self,
|
|
439
|
+
timestamp,
|
|
440
|
+
symbol,
|
|
441
|
+
exchange,
|
|
442
|
+
asset_type,
|
|
443
|
+
local_time,
|
|
444
|
+
exchange_time,
|
|
445
|
+
received_wall_time,
|
|
446
|
+
received_monotonic_ns,
|
|
447
|
+
clock_domain_id,
|
|
448
|
+
sequence,
|
|
449
|
+
previous_sequence,
|
|
450
|
+
snapshot_or_delta,
|
|
451
|
+
continuity_status,
|
|
452
|
+
stale,
|
|
453
|
+
stale_reason,
|
|
454
|
+
source,
|
|
455
|
+
event_id or _event_id(),
|
|
456
|
+
coalesced_count,
|
|
457
|
+
)
|
|
458
|
+
self.rate = rate
|
|
459
|
+
self.mark_price = mark_price
|
|
460
|
+
self.next_funding_time = next_funding_time
|
|
461
|
+
self.predicted_rate = predicted_rate
|
|
462
|
+
|
|
463
|
+
@property
|
|
464
|
+
def event_type(self) -> str:
|
|
465
|
+
"""Return the event type identifier.
|
|
466
|
+
|
|
467
|
+
Returns:
|
|
468
|
+
str: The string 'funding' for funding rate events.
|
|
469
|
+
"""
|
|
470
|
+
return "funding"
|
|
471
|
+
|
|
472
|
+
def validate(self) -> bool:
|
|
473
|
+
"""Validate funding event fields.
|
|
474
|
+
|
|
475
|
+
Checks:
|
|
476
|
+
- Common fields valid (via super)
|
|
477
|
+
- Mark price > 0
|
|
478
|
+
- Funding rate within reasonable range (-1, 1)
|
|
479
|
+
- Next funding time > current timestamp
|
|
480
|
+
"""
|
|
481
|
+
if not super().validate():
|
|
482
|
+
return False
|
|
483
|
+
if not isinstance(self.mark_price, (int, float)) or self.mark_price <= 0:
|
|
484
|
+
return False
|
|
485
|
+
if not isinstance(self.rate, (int, float)):
|
|
486
|
+
return False
|
|
487
|
+
if abs(self.rate) >= 1.0:
|
|
488
|
+
return False
|
|
489
|
+
if self.next_funding_time > 0 and self.next_funding_time < self.timestamp:
|
|
490
|
+
return False
|
|
491
|
+
return True
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
@dataclass(init=False)
|
|
495
|
+
class BarEvent(EventData):
|
|
496
|
+
"""OHLCV bar event data.
|
|
497
|
+
|
|
498
|
+
Compatible with existing backtrader bar-level data format.
|
|
499
|
+
|
|
500
|
+
Attributes:
|
|
501
|
+
open: Opening price.
|
|
502
|
+
high: Highest price.
|
|
503
|
+
low: Lowest price.
|
|
504
|
+
close: Closing price.
|
|
505
|
+
volume: Total volume during bar period.
|
|
506
|
+
openinterest: Open interest (for futures).
|
|
507
|
+
"""
|
|
508
|
+
|
|
509
|
+
open: float = 0.0
|
|
510
|
+
high: float = 0.0
|
|
511
|
+
low: float = 0.0
|
|
512
|
+
close: float = 0.0
|
|
513
|
+
volume: float = 0.0
|
|
514
|
+
openinterest: float = 0.0
|
|
515
|
+
|
|
516
|
+
def __init__(
|
|
517
|
+
self,
|
|
518
|
+
timestamp: float,
|
|
519
|
+
symbol: str,
|
|
520
|
+
exchange: str = "",
|
|
521
|
+
asset_type: str = "spot",
|
|
522
|
+
local_time: Optional[float] = None,
|
|
523
|
+
open: float = 0.0,
|
|
524
|
+
high: float = 0.0,
|
|
525
|
+
low: float = 0.0,
|
|
526
|
+
close: float = 0.0,
|
|
527
|
+
volume: float = 0.0,
|
|
528
|
+
openinterest: float = 0.0,
|
|
529
|
+
*,
|
|
530
|
+
exchange_time: Optional[float] = None,
|
|
531
|
+
received_wall_time: Optional[float] = None,
|
|
532
|
+
received_monotonic_ns: Optional[int] = None,
|
|
533
|
+
clock_domain_id: str = _CLOCK_DOMAIN_ID,
|
|
534
|
+
sequence: int = 0,
|
|
535
|
+
previous_sequence: Optional[int] = None,
|
|
536
|
+
snapshot_or_delta: str = "",
|
|
537
|
+
continuity_status: str = "unknown",
|
|
538
|
+
stale: bool = False,
|
|
539
|
+
stale_reason: str = "",
|
|
540
|
+
source: str = "",
|
|
541
|
+
event_id: Optional[str] = None,
|
|
542
|
+
coalesced_count: int = 1,
|
|
543
|
+
) -> None:
|
|
544
|
+
EventData.__init__(
|
|
545
|
+
self,
|
|
546
|
+
timestamp,
|
|
547
|
+
symbol,
|
|
548
|
+
exchange,
|
|
549
|
+
asset_type,
|
|
550
|
+
local_time,
|
|
551
|
+
exchange_time,
|
|
552
|
+
received_wall_time,
|
|
553
|
+
received_monotonic_ns,
|
|
554
|
+
clock_domain_id,
|
|
555
|
+
sequence,
|
|
556
|
+
previous_sequence,
|
|
557
|
+
snapshot_or_delta,
|
|
558
|
+
continuity_status,
|
|
559
|
+
stale,
|
|
560
|
+
stale_reason,
|
|
561
|
+
source,
|
|
562
|
+
event_id or _event_id(),
|
|
563
|
+
coalesced_count,
|
|
564
|
+
)
|
|
565
|
+
self.open = open
|
|
566
|
+
self.high = high
|
|
567
|
+
self.low = low
|
|
568
|
+
self.close = close
|
|
569
|
+
self.volume = volume
|
|
570
|
+
self.openinterest = openinterest
|
|
571
|
+
|
|
572
|
+
@property
|
|
573
|
+
def event_type(self) -> str:
|
|
574
|
+
"""Return the event type identifier.
|
|
575
|
+
|
|
576
|
+
Returns:
|
|
577
|
+
str: The string 'bar' for OHLCV bar events.
|
|
578
|
+
"""
|
|
579
|
+
return "bar"
|
|
580
|
+
|
|
581
|
+
def validate(self) -> bool:
|
|
582
|
+
"""Validate bar event fields.
|
|
583
|
+
|
|
584
|
+
Checks:
|
|
585
|
+
- Common fields valid (via super)
|
|
586
|
+
- All OHLC prices > 0
|
|
587
|
+
- High >= Low
|
|
588
|
+
- High >= Open, Close
|
|
589
|
+
- Low <= Open, Close
|
|
590
|
+
- Volume >= 0
|
|
591
|
+
"""
|
|
592
|
+
if not super().validate():
|
|
593
|
+
return False
|
|
594
|
+
for price in (self.open, self.high, self.low, self.close):
|
|
595
|
+
if not isinstance(price, (int, float)) or price <= 0:
|
|
596
|
+
return False
|
|
597
|
+
if self.high < self.low:
|
|
598
|
+
return False
|
|
599
|
+
if self.high < self.open or self.high < self.close:
|
|
600
|
+
return False
|
|
601
|
+
if self.low > self.open or self.low > self.close:
|
|
602
|
+
return False
|
|
603
|
+
if not isinstance(self.volume, (int, float)) or self.volume < 0:
|
|
604
|
+
return False
|
|
605
|
+
return True
|
|
606
|
+
|
|
607
|
+
|
|
608
|
+
# --- Adapter classes for backward compatibility ---
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
class TickEventAdapter:
|
|
612
|
+
"""Adapter: TickEvent -> TickerData interface.
|
|
613
|
+
|
|
614
|
+
Wraps a TickEvent to provide the TickerData interface for backward
|
|
615
|
+
compatibility with existing code that uses TickerData.
|
|
616
|
+
|
|
617
|
+
Example::
|
|
618
|
+
|
|
619
|
+
tick = TickEvent(timestamp=100.0, symbol='BTC/USDT', price=50000, volume=1.0, direction='buy')
|
|
620
|
+
adapter = TickEventAdapter(tick)
|
|
621
|
+
assert adapter.get_last_price() == 50000
|
|
622
|
+
|
|
623
|
+
Attributes:
|
|
624
|
+
event: Event type identifier string.
|
|
625
|
+
_tick: The underlying TickEvent instance.
|
|
626
|
+
"""
|
|
627
|
+
|
|
628
|
+
def __init__(self, tick_event: TickEvent):
|
|
629
|
+
"""Initialize the adapter with a TickEvent.
|
|
630
|
+
|
|
631
|
+
Args:
|
|
632
|
+
tick_event: The TickEvent instance to wrap.
|
|
633
|
+
"""
|
|
634
|
+
self.event = "TickerEvent"
|
|
635
|
+
self._tick = tick_event
|
|
636
|
+
|
|
637
|
+
def get_event(self):
|
|
638
|
+
"""Return the event type identifier.
|
|
639
|
+
|
|
640
|
+
Returns:
|
|
641
|
+
str: The event type string "TickerEvent".
|
|
642
|
+
"""
|
|
643
|
+
return self.event
|
|
644
|
+
|
|
645
|
+
def get_exchange_name(self):
|
|
646
|
+
"""Return the exchange name from the tick event.
|
|
647
|
+
|
|
648
|
+
Returns:
|
|
649
|
+
str: The exchange name (e.g., 'binance').
|
|
650
|
+
"""
|
|
651
|
+
return self._tick.exchange
|
|
652
|
+
|
|
653
|
+
def get_local_update_time(self):
|
|
654
|
+
"""Return the local update timestamp.
|
|
655
|
+
|
|
656
|
+
Returns:
|
|
657
|
+
float: The local receive timestamp, or the server timestamp if
|
|
658
|
+
local_time is not set.
|
|
659
|
+
"""
|
|
660
|
+
return self._tick.local_time or self._tick.timestamp
|
|
661
|
+
|
|
662
|
+
def get_symbol_name(self):
|
|
663
|
+
"""Return the trading pair symbol.
|
|
664
|
+
|
|
665
|
+
Returns:
|
|
666
|
+
str: The symbol name (e.g., 'BTC/USDT').
|
|
667
|
+
"""
|
|
668
|
+
return self._tick.symbol
|
|
669
|
+
|
|
670
|
+
def get_asset_type(self):
|
|
671
|
+
"""Return the asset type.
|
|
672
|
+
|
|
673
|
+
Returns:
|
|
674
|
+
str: The asset type ('spot', 'swap', or 'futures').
|
|
675
|
+
"""
|
|
676
|
+
return self._tick.asset_type
|
|
677
|
+
|
|
678
|
+
def get_server_time(self):
|
|
679
|
+
"""Return the server timestamp from the tick event.
|
|
680
|
+
|
|
681
|
+
Returns:
|
|
682
|
+
float: The Unix timestamp in seconds.
|
|
683
|
+
"""
|
|
684
|
+
return self._tick.timestamp
|
|
685
|
+
|
|
686
|
+
def get_bid_price(self):
|
|
687
|
+
"""Return the best bid price.
|
|
688
|
+
|
|
689
|
+
Returns:
|
|
690
|
+
Optional[float]: The best bid price, or None if not available.
|
|
691
|
+
"""
|
|
692
|
+
return self._tick.bid_price
|
|
693
|
+
|
|
694
|
+
def get_ask_price(self):
|
|
695
|
+
"""Return the best ask price.
|
|
696
|
+
|
|
697
|
+
Returns:
|
|
698
|
+
Optional[float]: The best ask price, or None if not available.
|
|
699
|
+
"""
|
|
700
|
+
return self._tick.ask_price
|
|
701
|
+
|
|
702
|
+
def get_bid_volume(self):
|
|
703
|
+
"""Return the best bid volume.
|
|
704
|
+
|
|
705
|
+
Returns:
|
|
706
|
+
Optional[float]: The best bid volume, or None if not available.
|
|
707
|
+
"""
|
|
708
|
+
return self._tick.bid_volume
|
|
709
|
+
|
|
710
|
+
def get_ask_volume(self):
|
|
711
|
+
"""Return the best ask volume.
|
|
712
|
+
|
|
713
|
+
Returns:
|
|
714
|
+
Optional[float]: The best ask volume, or None if not available.
|
|
715
|
+
"""
|
|
716
|
+
return self._tick.ask_volume
|
|
717
|
+
|
|
718
|
+
def get_last_price(self):
|
|
719
|
+
"""Return the last trade price.
|
|
720
|
+
|
|
721
|
+
Returns:
|
|
722
|
+
float: The last execution price.
|
|
723
|
+
"""
|
|
724
|
+
return self._tick.price
|
|
725
|
+
|
|
726
|
+
def get_last_volume(self):
|
|
727
|
+
"""Return the last trade volume.
|
|
728
|
+
|
|
729
|
+
Returns:
|
|
730
|
+
float: The last execution volume/amount.
|
|
731
|
+
"""
|
|
732
|
+
return self._tick.volume
|
|
733
|
+
|
|
734
|
+
def __str__(self):
|
|
735
|
+
"""Return a string representation of the adapter.
|
|
736
|
+
|
|
737
|
+
Returns:
|
|
738
|
+
str: A descriptive string showing symbol, price, volume, and direction.
|
|
739
|
+
"""
|
|
740
|
+
return (
|
|
741
|
+
f"TickEventAdapter({self._tick.symbol} "
|
|
742
|
+
f"price={self._tick.price} vol={self._tick.volume} "
|
|
743
|
+
f"dir={self._tick.direction})"
|
|
744
|
+
)
|
|
745
|
+
|
|
746
|
+
def __repr__(self):
|
|
747
|
+
"""Return the string representation for debugging.
|
|
748
|
+
|
|
749
|
+
Returns:
|
|
750
|
+
str: Same as __str__().
|
|
751
|
+
"""
|
|
752
|
+
return self.__str__()
|
|
753
|
+
|
|
754
|
+
|
|
755
|
+
class OrderBookEventAdapter:
|
|
756
|
+
"""Adapter: OrderBookSnapshot -> OrderBookData interface.
|
|
757
|
+
|
|
758
|
+
Wraps an OrderBookSnapshot to provide the OrderBookData interface for
|
|
759
|
+
backward compatibility with existing code.
|
|
760
|
+
|
|
761
|
+
Attributes:
|
|
762
|
+
event: Event type identifier string.
|
|
763
|
+
_ob: The underlying OrderBookSnapshot instance.
|
|
764
|
+
"""
|
|
765
|
+
|
|
766
|
+
def __init__(self, ob_event: OrderBookSnapshot):
|
|
767
|
+
"""Initialize the adapter with an OrderBookSnapshot.
|
|
768
|
+
|
|
769
|
+
Args:
|
|
770
|
+
ob_event: The OrderBookSnapshot instance to wrap.
|
|
771
|
+
"""
|
|
772
|
+
self.event = "OrderBookEvent"
|
|
773
|
+
self._ob = ob_event
|
|
774
|
+
|
|
775
|
+
def get_event(self):
|
|
776
|
+
"""Return the event type identifier.
|
|
777
|
+
|
|
778
|
+
Returns:
|
|
779
|
+
str: The event type string "OrderBookEvent".
|
|
780
|
+
"""
|
|
781
|
+
return self.event
|
|
782
|
+
|
|
783
|
+
def get_exchange_name(self):
|
|
784
|
+
"""Return the exchange name from the order book event.
|
|
785
|
+
|
|
786
|
+
Returns:
|
|
787
|
+
str: The exchange name (e.g., 'binance').
|
|
788
|
+
"""
|
|
789
|
+
return self._ob.exchange
|
|
790
|
+
|
|
791
|
+
def get_local_update_time(self):
|
|
792
|
+
"""Return the local update timestamp.
|
|
793
|
+
|
|
794
|
+
Returns:
|
|
795
|
+
float: The local receive timestamp, or the server timestamp if
|
|
796
|
+
local_time is not set.
|
|
797
|
+
"""
|
|
798
|
+
return self._ob.local_time or self._ob.timestamp
|
|
799
|
+
|
|
800
|
+
def get_symbol_name(self):
|
|
801
|
+
"""Return the trading pair symbol.
|
|
802
|
+
|
|
803
|
+
Returns:
|
|
804
|
+
str: The symbol name (e.g., 'BTC/USDT').
|
|
805
|
+
"""
|
|
806
|
+
return self._ob.symbol
|
|
807
|
+
|
|
808
|
+
def get_asset_type(self):
|
|
809
|
+
"""Return the asset type.
|
|
810
|
+
|
|
811
|
+
Returns:
|
|
812
|
+
str: The asset type ('spot', 'swap', or 'futures').
|
|
813
|
+
"""
|
|
814
|
+
return self._ob.asset_type
|
|
815
|
+
|
|
816
|
+
def get_server_time(self):
|
|
817
|
+
"""Return the server timestamp from the order book event.
|
|
818
|
+
|
|
819
|
+
Returns:
|
|
820
|
+
float: The Unix timestamp in seconds.
|
|
821
|
+
"""
|
|
822
|
+
return self._ob.timestamp
|
|
823
|
+
|
|
824
|
+
def get_bid_price_list(self):
|
|
825
|
+
"""Return a list of bid prices.
|
|
826
|
+
|
|
827
|
+
Returns:
|
|
828
|
+
List[float]: List of bid prices in descending order.
|
|
829
|
+
"""
|
|
830
|
+
return [b[0] for b in self._ob.bids]
|
|
831
|
+
|
|
832
|
+
def get_ask_price_list(self):
|
|
833
|
+
"""Return a list of ask prices.
|
|
834
|
+
|
|
835
|
+
Returns:
|
|
836
|
+
List[float]: List of ask prices in ascending order.
|
|
837
|
+
"""
|
|
838
|
+
return [a[0] for a in self._ob.asks]
|
|
839
|
+
|
|
840
|
+
def get_bid_volume_list(self):
|
|
841
|
+
"""Return a list of bid volumes.
|
|
842
|
+
|
|
843
|
+
Returns:
|
|
844
|
+
List[float]: List of bid quantities corresponding to bid prices.
|
|
845
|
+
"""
|
|
846
|
+
return [b[1] for b in self._ob.bids]
|
|
847
|
+
|
|
848
|
+
def get_ask_volume_list(self):
|
|
849
|
+
"""Return a list of ask volumes.
|
|
850
|
+
|
|
851
|
+
Returns:
|
|
852
|
+
List[float]: List of ask quantities corresponding to ask prices.
|
|
853
|
+
"""
|
|
854
|
+
return [a[1] for a in self._ob.asks]
|
|
855
|
+
|
|
856
|
+
def __str__(self):
|
|
857
|
+
"""Return a string representation of the adapter.
|
|
858
|
+
|
|
859
|
+
Returns:
|
|
860
|
+
str: A descriptive string showing symbol, best bid, and best ask.
|
|
861
|
+
"""
|
|
862
|
+
return f"OrderBookEventAdapter({self._ob.symbol} bid={self._ob.best_bid} ask={self._ob.best_ask})"
|
|
863
|
+
|
|
864
|
+
def __repr__(self):
|
|
865
|
+
"""Return the string representation for debugging.
|
|
866
|
+
|
|
867
|
+
Returns:
|
|
868
|
+
str: Same as __str__().
|
|
869
|
+
"""
|
|
870
|
+
return self.__str__()
|
|
871
|
+
|
|
872
|
+
|
|
873
|
+
class FundingEventAdapter:
|
|
874
|
+
"""Adapter: FundingEvent -> FundingRateData interface.
|
|
875
|
+
|
|
876
|
+
Wraps a FundingEvent to provide the FundingRateData interface for
|
|
877
|
+
backward compatibility with existing code.
|
|
878
|
+
|
|
879
|
+
Attributes:
|
|
880
|
+
event: Event type identifier string.
|
|
881
|
+
_funding: The underlying FundingEvent instance.
|
|
882
|
+
"""
|
|
883
|
+
|
|
884
|
+
def __init__(self, funding_event: FundingEvent):
|
|
885
|
+
"""Initialize the adapter with a FundingEvent.
|
|
886
|
+
|
|
887
|
+
Args:
|
|
888
|
+
funding_event: The FundingEvent instance to wrap.
|
|
889
|
+
"""
|
|
890
|
+
self.event = "FundingEvent"
|
|
891
|
+
self._funding = funding_event
|
|
892
|
+
|
|
893
|
+
def get_event_type(self):
|
|
894
|
+
"""Return the event type identifier.
|
|
895
|
+
|
|
896
|
+
Returns:
|
|
897
|
+
str: The event type string "FundingEvent".
|
|
898
|
+
"""
|
|
899
|
+
return self.event
|
|
900
|
+
|
|
901
|
+
def get_exchange_name(self):
|
|
902
|
+
"""Return the exchange name from the funding event.
|
|
903
|
+
|
|
904
|
+
Returns:
|
|
905
|
+
str: The exchange name (e.g., 'binance').
|
|
906
|
+
"""
|
|
907
|
+
return self._funding.exchange
|
|
908
|
+
|
|
909
|
+
def get_server_time(self):
|
|
910
|
+
"""Return the server timestamp from the funding event.
|
|
911
|
+
|
|
912
|
+
Returns:
|
|
913
|
+
float: The Unix timestamp in seconds.
|
|
914
|
+
"""
|
|
915
|
+
return self._funding.timestamp
|
|
916
|
+
|
|
917
|
+
def get_local_update_time(self):
|
|
918
|
+
"""Return the local update timestamp.
|
|
919
|
+
|
|
920
|
+
Returns:
|
|
921
|
+
float: The local receive timestamp, or the server timestamp if
|
|
922
|
+
local_time is not set.
|
|
923
|
+
"""
|
|
924
|
+
return self._funding.local_time or self._funding.timestamp
|
|
925
|
+
|
|
926
|
+
def get_asset_type(self):
|
|
927
|
+
"""Return the asset type.
|
|
928
|
+
|
|
929
|
+
Returns:
|
|
930
|
+
str: The asset type ('spot', 'swap', or 'futures').
|
|
931
|
+
"""
|
|
932
|
+
return self._funding.asset_type
|
|
933
|
+
|
|
934
|
+
def get_symbol_name(self):
|
|
935
|
+
"""Return the trading pair symbol.
|
|
936
|
+
|
|
937
|
+
Returns:
|
|
938
|
+
str: The symbol name (e.g., 'BTC/USDT').
|
|
939
|
+
"""
|
|
940
|
+
return self._funding.symbol
|
|
941
|
+
|
|
942
|
+
def get_current_funding_rate(self):
|
|
943
|
+
"""Return the current funding rate.
|
|
944
|
+
|
|
945
|
+
Returns:
|
|
946
|
+
float: The current funding rate as a decimal (e.g., 0.0001 for 0.01%).
|
|
947
|
+
"""
|
|
948
|
+
return self._funding.rate
|
|
949
|
+
|
|
950
|
+
def get_next_funding_time(self):
|
|
951
|
+
"""Return the timestamp of the next funding settlement.
|
|
952
|
+
|
|
953
|
+
Returns:
|
|
954
|
+
float: The Unix timestamp of the next funding payment.
|
|
955
|
+
"""
|
|
956
|
+
return self._funding.next_funding_time
|
|
957
|
+
|
|
958
|
+
def get_next_funding_rate(self):
|
|
959
|
+
"""Return the predicted next funding rate.
|
|
960
|
+
|
|
961
|
+
Returns:
|
|
962
|
+
float: The predicted funding rate for the next period.
|
|
963
|
+
"""
|
|
964
|
+
return self._funding.predicted_rate
|
|
965
|
+
|
|
966
|
+
def __str__(self):
|
|
967
|
+
"""Return a string representation of the adapter.
|
|
968
|
+
|
|
969
|
+
Returns:
|
|
970
|
+
str: A descriptive string showing symbol and funding rate.
|
|
971
|
+
"""
|
|
972
|
+
return f"FundingEventAdapter({self._funding.symbol} rate={self._funding.rate})"
|
|
973
|
+
|
|
974
|
+
def __repr__(self):
|
|
975
|
+
"""Return the string representation for debugging.
|
|
976
|
+
|
|
977
|
+
Returns:
|
|
978
|
+
str: Same as __str__().
|
|
979
|
+
"""
|
|
980
|
+
return self.__str__()
|