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.
Files changed (465) hide show
  1. back_trader_python-1.4.0.dist-info/METADATA +1491 -0
  2. back_trader_python-1.4.0.dist-info/RECORD +465 -0
  3. back_trader_python-1.4.0.dist-info/WHEEL +5 -0
  4. back_trader_python-1.4.0.dist-info/licenses/LICENSE +674 -0
  5. back_trader_python-1.4.0.dist-info/top_level.txt +1 -0
  6. backtrader/__init__.py +148 -0
  7. backtrader/_cerebro/__init__.py +5 -0
  8. backtrader/_cerebro/channel.py +382 -0
  9. backtrader/_cerebro/execution.py +377 -0
  10. backtrader/_cerebro/lifecycle.py +143 -0
  11. backtrader/_cerebro/notifications.py +150 -0
  12. backtrader/_cerebro/presentation.py +230 -0
  13. backtrader/_cerebro/registry.py +593 -0
  14. backtrader/_cerebro/runnext.py +551 -0
  15. backtrader/_cerebro/runonce.py +142 -0
  16. backtrader/analyzer.py +594 -0
  17. backtrader/analyzers/__init__.py +50 -0
  18. backtrader/analyzers/annualreturn.py +226 -0
  19. backtrader/analyzers/calmar.py +165 -0
  20. backtrader/analyzers/drawdown.py +287 -0
  21. backtrader/analyzers/leverage.py +112 -0
  22. backtrader/analyzers/logreturnsrolling.py +190 -0
  23. backtrader/analyzers/periodstats.py +153 -0
  24. backtrader/analyzers/positions.py +119 -0
  25. backtrader/analyzers/pyfolio.py +470 -0
  26. backtrader/analyzers/returns.py +192 -0
  27. backtrader/analyzers/sharpe.py +307 -0
  28. backtrader/analyzers/sharpe_ratio_stats.py +534 -0
  29. backtrader/analyzers/sqn.py +112 -0
  30. backtrader/analyzers/timereturn.py +192 -0
  31. backtrader/analyzers/total_value.py +75 -0
  32. backtrader/analyzers/tradeanalyzer.py +278 -0
  33. backtrader/analyzers/transactions.py +141 -0
  34. backtrader/analyzers/vwr.py +245 -0
  35. backtrader/bokeh/__init__.py +155 -0
  36. backtrader/bokeh/analyzers/__init__.py +13 -0
  37. backtrader/bokeh/analyzers/plot.py +192 -0
  38. backtrader/bokeh/analyzers/recorder.py +181 -0
  39. backtrader/bokeh/app.py +1094 -0
  40. backtrader/bokeh/live/__init__.py +11 -0
  41. backtrader/bokeh/live/client.py +352 -0
  42. backtrader/bokeh/live/datahandler.py +346 -0
  43. backtrader/bokeh/plot_adapter.py +200 -0
  44. backtrader/bokeh/schemes/__init__.py +14 -0
  45. backtrader/bokeh/schemes/blackly.py +76 -0
  46. backtrader/bokeh/schemes/scheme.py +150 -0
  47. backtrader/bokeh/schemes/tradimo.py +82 -0
  48. backtrader/bokeh/tab.py +125 -0
  49. backtrader/bokeh/tabs/__init__.py +30 -0
  50. backtrader/bokeh/tabs/analyzer.py +120 -0
  51. backtrader/bokeh/tabs/config.py +154 -0
  52. backtrader/bokeh/tabs/live.py +109 -0
  53. backtrader/bokeh/tabs/log.py +185 -0
  54. backtrader/bokeh/tabs/metadata.py +182 -0
  55. backtrader/bokeh/tabs/performance.py +359 -0
  56. backtrader/bokeh/tabs/source.py +70 -0
  57. backtrader/bokeh/utils/__init__.py +8 -0
  58. backtrader/bokeh/utils/helpers.py +167 -0
  59. backtrader/bokeh/webapp.py +164 -0
  60. backtrader/broker.py +478 -0
  61. backtrader/brokers/__init__.py +36 -0
  62. backtrader/brokers/bbroker.py +2576 -0
  63. backtrader/brokers/btapibroker.py +8227 -0
  64. backtrader/brokers/hft/__init__.py +89 -0
  65. backtrader/brokers/hft/binance_bbo.py +625 -0
  66. backtrader/brokers/hft/binance_bbo_compare.py +1398 -0
  67. backtrader/brokers/hft/examples.py +1228 -0
  68. backtrader/brokers/hft/exchange.py +380 -0
  69. backtrader/brokers/hft/latency.py +309 -0
  70. backtrader/brokers/hft/matching_core.py +572 -0
  71. backtrader/brokers/hft/queue.py +238 -0
  72. backtrader/brokers/hft/recorder.py +88 -0
  73. backtrader/brokers/hft/state.py +138 -0
  74. backtrader/brokers/impact_models.py +118 -0
  75. backtrader/brokers/mixbroker.py +895 -0
  76. backtrader/brokers/tickbroker.py +1991 -0
  77. backtrader/btrun/__init__.py +12 -0
  78. backtrader/btrun/btrun.py +1218 -0
  79. backtrader/cerebro.py +828 -0
  80. backtrader/channel.py +682 -0
  81. backtrader/channels/__init__.py +23 -0
  82. backtrader/channels/bridge.py +186 -0
  83. backtrader/channels/funding.py +248 -0
  84. backtrader/channels/live_queue.py +216 -0
  85. backtrader/channels/live_validator.py +294 -0
  86. backtrader/channels/orderbook.py +257 -0
  87. backtrader/channels/tick.py +202 -0
  88. backtrader/comminfo.py +665 -0
  89. backtrader/commissions/__init__.py +106 -0
  90. backtrader/commissions/ctpoption.py +993 -0
  91. backtrader/configs/account_config_example.yaml +8 -0
  92. backtrader/dataseries.py +379 -0
  93. backtrader/errors.py +106 -0
  94. backtrader/events.py +980 -0
  95. backtrader/feed.py +1523 -0
  96. backtrader/feeds/__init__.py +75 -0
  97. backtrader/feeds/barrier.py +2006 -0
  98. backtrader/feeds/blaze.py +118 -0
  99. backtrader/feeds/btapifeed.py +1538 -0
  100. backtrader/feeds/btcsv.py +203 -0
  101. backtrader/feeds/chainer.py +114 -0
  102. backtrader/feeds/cryptohftdata.py +164 -0
  103. backtrader/feeds/csvgeneric.py +1205 -0
  104. backtrader/feeds/ctpcohort.py +1051 -0
  105. backtrader/feeds/influxfeed.py +158 -0
  106. backtrader/feeds/livefeed.py +71 -0
  107. backtrader/feeds/mixed_channel.py +108 -0
  108. backtrader/feeds/mt4csv.py +42 -0
  109. backtrader/feeds/pandafeed.py +381 -0
  110. backtrader/feeds/quandl.py +256 -0
  111. backtrader/feeds/rollover.py +229 -0
  112. backtrader/feeds/sierrachart.py +30 -0
  113. backtrader/feeds/vchart.py +162 -0
  114. backtrader/feeds/vchartcsv.py +84 -0
  115. backtrader/feeds/vchartfile.py +153 -0
  116. backtrader/feeds/yahoo.py +399 -0
  117. backtrader/fillers.py +148 -0
  118. backtrader/filters/__init__.py +34 -0
  119. backtrader/filters/bsplitter.py +127 -0
  120. backtrader/filters/calendardays.py +121 -0
  121. backtrader/filters/datafiller.py +192 -0
  122. backtrader/filters/datafilter.py +74 -0
  123. backtrader/filters/daysteps.py +96 -0
  124. backtrader/filters/heikinashi.py +63 -0
  125. backtrader/filters/renko.py +164 -0
  126. backtrader/filters/session.py +289 -0
  127. backtrader/flt.py +80 -0
  128. backtrader/functions.py +960 -0
  129. backtrader/indicator.py +449 -0
  130. backtrader/indicators/__init__.py +148 -0
  131. backtrader/indicators/accdecoscillator.py +110 -0
  132. backtrader/indicators/aroon.py +300 -0
  133. backtrader/indicators/atr.py +315 -0
  134. backtrader/indicators/awesomeoscillator.py +122 -0
  135. backtrader/indicators/basicops.py +834 -0
  136. backtrader/indicators/bollinger.py +223 -0
  137. backtrader/indicators/cci.py +89 -0
  138. backtrader/indicators/channels_ext.py +83 -0
  139. backtrader/indicators/contrib/__init__.py +228 -0
  140. backtrader/indicators/contrib/absolutely_no_lag_lwma.py +28 -0
  141. backtrader/indicators/contrib/absolutely_no_lag_lwma_color.py +44 -0
  142. backtrader/indicators/contrib/accumulation_distribution_line.py +92 -0
  143. backtrader/indicators/contrib/adx_cross_hull_style_indicator.py +249 -0
  144. backtrader/indicators/contrib/adxdmi.py +34 -0
  145. backtrader/indicators/contrib/ai_acceleration_deceleration_oscillator.py +34 -0
  146. backtrader/indicators/contrib/altr_trend_signal_v22.py +85 -0
  147. backtrader/indicators/contrib/anchored_momentum_line.py +115 -0
  148. backtrader/indicators/contrib/any_range_cld_tail_indicator.py +82 -0
  149. backtrader/indicators/contrib/aroon_horn_sign_indicator.py +96 -0
  150. backtrader/indicators/contrib/aroon_oscillator_sign_alert.py +50 -0
  151. backtrader/indicators/contrib/arrows_curves_indicator.py +112 -0
  152. backtrader/indicators/contrib/as_ctrend_indicator.py +143 -0
  153. backtrader/indicators/contrib/asimmetric_stoch_nr_indicator.py +187 -0
  154. backtrader/indicators/contrib/atr_normalize_histogram.py +118 -0
  155. backtrader/indicators/contrib/average_change_candle.py +165 -0
  156. backtrader/indicators/contrib/bb_squeeze_indicator.py +60 -0
  157. backtrader/indicators/contrib/bezier_st_dev_indicator.py +135 -0
  158. backtrader/indicators/contrib/binary_wave_indicator.py +233 -0
  159. backtrader/indicators/contrib/blau_c_momentum_indicator.py +123 -0
  160. backtrader/indicators/contrib/blau_cmi_indicator.py +141 -0
  161. backtrader/indicators/contrib/blau_csi.py +76 -0
  162. backtrader/indicators/contrib/blau_ergodic.py +53 -0
  163. backtrader/indicators/contrib/blau_t_stoch_i.py +72 -0
  164. backtrader/indicators/contrib/blau_ts_stochastic.py +85 -0
  165. backtrader/indicators/contrib/blau_tvi.py +55 -0
  166. backtrader/indicators/contrib/brain_trend2_indicator.py +128 -0
  167. backtrader/indicators/contrib/brain_trend_signal_proxy.py +47 -0
  168. backtrader/indicators/contrib/brake_parb_indicator.py +85 -0
  169. backtrader/indicators/contrib/breakout_bars_trend_v2.py +121 -0
  170. backtrader/indicators/contrib/bsi_indicator.py +87 -0
  171. backtrader/indicators/contrib/bulls_bears_eyes.py +67 -0
  172. backtrader/indicators/contrib/bulls_power.py +56 -0
  173. backtrader/indicators/contrib/bw_wise_man1_signal.py +102 -0
  174. backtrader/indicators/contrib/bykov_trend_indicator.py +85 -0
  175. backtrader/indicators/contrib/candle_stop_color.py +46 -0
  176. backtrader/indicators/contrib/candles_x_smoothed_indicator.py +69 -0
  177. backtrader/indicators/contrib/candlesticks_bw.py +45 -0
  178. backtrader/indicators/contrib/caudate_x_period_candle_color.py +56 -0
  179. backtrader/indicators/contrib/cci_histogram_indicator.py +53 -0
  180. backtrader/indicators/contrib/cci_woodies_indicator.py +80 -0
  181. backtrader/indicators/contrib/center_of_gravity_candle_indicator.py +83 -0
  182. backtrader/indicators/contrib/center_of_gravity_indicator.py +70 -0
  183. backtrader/indicators/contrib/cg_oscillator.py +40 -0
  184. backtrader/indicators/contrib/close_line_cci.py +38 -0
  185. backtrader/indicators/contrib/close_price_fractals.py +47 -0
  186. backtrader/indicators/contrib/color3rd_gen_xma_indicator.py +122 -0
  187. backtrader/indicators/contrib/color_bb_candles_indicator.py +108 -0
  188. backtrader/indicators/contrib/color_coppock_indicator.py +157 -0
  189. backtrader/indicators/contrib/color_hma.py +71 -0
  190. backtrader/indicators/contrib/color_j_variation_indicator.py +53 -0
  191. backtrader/indicators/contrib/color_metro_de_marker_indicator.py +78 -0
  192. backtrader/indicators/contrib/color_metro_stochastic_indicator.py +93 -0
  193. backtrader/indicators/contrib/color_metro_wpr_indicator.py +85 -0
  194. backtrader/indicators/contrib/color_schaff_de_marker_trend_cycle.py +92 -0
  195. backtrader/indicators/contrib/color_schaff_trend_cycle_indicator.py +203 -0
  196. backtrader/indicators/contrib/color_step_xccx_indicator.py +193 -0
  197. backtrader/indicators/contrib/color_x2_ma.py +49 -0
  198. backtrader/indicators/contrib/color_x_derivative.py +63 -0
  199. backtrader/indicators/contrib/color_zerolag_de_marker.py +84 -0
  200. backtrader/indicators/contrib/corrected_average_indicator.py +127 -0
  201. backtrader/indicators/contrib/darvas_boxes_system.py +73 -0
  202. backtrader/indicators/contrib/dema_range_channel_color.py +42 -0
  203. backtrader/indicators/contrib/derivative_indicator.py +95 -0
  204. backtrader/indicators/contrib/digital_ft01_indicator.py +112 -0
  205. backtrader/indicators/contrib/digital_macd.py +200 -0
  206. backtrader/indicators/contrib/donchian_channels_system.py +45 -0
  207. backtrader/indicators/contrib/dots_indicator.py +93 -0
  208. backtrader/indicators/contrib/ef_distance_indicator.py +82 -0
  209. backtrader/indicators/contrib/ema_rsi_va.py +80 -0
  210. backtrader/indicators/contrib/envelopes_jp_alonso.py +32 -0
  211. backtrader/indicators/contrib/f2a_ao_indicator.py +120 -0
  212. backtrader/indicators/contrib/fatl_filter.py +179 -0
  213. backtrader/indicators/contrib/fibo_candles_indicator.py +78 -0
  214. backtrader/indicators/contrib/fine_tuning_ma.py +100 -0
  215. backtrader/indicators/contrib/fisher_org_v1.py +102 -0
  216. backtrader/indicators/contrib/fisher_org_v1_sign.py +118 -0
  217. backtrader/indicators/contrib/force_index_ema.py +96 -0
  218. backtrader/indicators/contrib/force_index_ema_2.py +27 -0
  219. backtrader/indicators/contrib/forecast_oscilator.py +145 -0
  220. backtrader/indicators/contrib/fractal_amambk.py +81 -0
  221. backtrader/indicators/contrib/frama_series.py +84 -0
  222. backtrader/indicators/contrib/frasm_av2_indicator.py +104 -0
  223. backtrader/indicators/contrib/go_indicator.py +93 -0
  224. backtrader/indicators/contrib/hlr_indicator.py +95 -0
  225. backtrader/indicators/contrib/hma.py +50 -0
  226. backtrader/indicators/contrib/i4_drfv2.py +34 -0
  227. backtrader/indicators/contrib/i4_drfv3.py +38 -0
  228. backtrader/indicators/contrib/i_anch_mom_indicator.py +72 -0
  229. backtrader/indicators/contrib/i_de_marker_sign_indicator.py +64 -0
  230. backtrader/indicators/contrib/i_gap_indicator.py +45 -0
  231. backtrader/indicators/contrib/i_stoch_komposter_indicator.py +77 -0
  232. backtrader/indicators/contrib/i_trend_indicator.py +125 -0
  233. backtrader/indicators/contrib/iamma_indicator.py +39 -0
  234. backtrader/indicators/contrib/indexed_moving_average.py +33 -0
  235. backtrader/indicators/contrib/instantaneous_trend_filter_indicator.py +51 -0
  236. backtrader/indicators/contrib/inverse_reaction_indicator.py +41 -0
  237. backtrader/indicators/contrib/irsi_sign_indicator.py +95 -0
  238. backtrader/indicators/contrib/iwpr_sign_indicator.py +59 -0
  239. backtrader/indicators/contrib/j_brain_trend1_sig_indicator.py +233 -0
  240. backtrader/indicators/contrib/j_tpo_proxy.py +32 -0
  241. backtrader/indicators/contrib/jma_slope_indicator.py +73 -0
  242. backtrader/indicators/contrib/kalman_filter_indicator.py +119 -0
  243. backtrader/indicators/contrib/kalman_filter_line.py +127 -0
  244. backtrader/indicators/contrib/kama_indicator.py +150 -0
  245. backtrader/indicators/contrib/karacatica_indicator.py +99 -0
  246. backtrader/indicators/contrib/kdj_indicator.py +59 -0
  247. backtrader/indicators/contrib/kwan_ccc_indicator.py +195 -0
  248. backtrader/indicators/contrib/kwan_nrp_indicator.py +113 -0
  249. backtrader/indicators/contrib/kwan_rdp_indicator.py +192 -0
  250. backtrader/indicators/contrib/laguerre_adx_indicator.py +85 -0
  251. backtrader/indicators/contrib/laguerre_filter_indicator.py +66 -0
  252. backtrader/indicators/contrib/laguerre_plus_di_proxy.py +57 -0
  253. backtrader/indicators/contrib/laguerre_roc_indicator.py +81 -0
  254. backtrader/indicators/contrib/le_man_signal_indicator.py +63 -0
  255. backtrader/indicators/contrib/linear_reg_slope_v2_indicator.py +136 -0
  256. backtrader/indicators/contrib/loco_indicator.py +88 -0
  257. backtrader/indicators/contrib/lrma_indicator.py +185 -0
  258. backtrader/indicators/contrib/lsma_angle_indicator.py +106 -0
  259. backtrader/indicators/contrib/ma_rounding_channel_indicator.py +149 -0
  260. backtrader/indicators/contrib/macd2_indicator.py +61 -0
  261. backtrader/indicators/contrib/macd_candle_indicator.py +80 -0
  262. backtrader/indicators/contrib/malr_indicator.py +77 -0
  263. backtrader/indicators/contrib/momentum_candle_sign_indicator.py +51 -0
  264. backtrader/indicators/contrib/moving_average_fn_indicator.py +139 -0
  265. backtrader/indicators/contrib/mt5_stochastic_close_close.py +57 -0
  266. backtrader/indicators/contrib/muv_nor_diff_cloud_indicator.py +107 -0
  267. backtrader/indicators/contrib/non_lag_dot_indicator.py +124 -0
  268. backtrader/indicators/contrib/nrtr_extr_indicator.py +95 -0
  269. backtrader/indicators/contrib/nrtr_indicator.py +95 -0
  270. backtrader/indicators/contrib/p_channel_system.py +40 -0
  271. backtrader/indicators/contrib/percent_envelope.py +37 -0
  272. backtrader/indicators/contrib/percentage_crossover_channel.py +47 -0
  273. backtrader/indicators/contrib/pivot_zig_zag_proxy.py +47 -0
  274. backtrader/indicators/contrib/price_channel_stop_indicator.py +104 -0
  275. backtrader/indicators/contrib/price_extreme_channel.py +35 -0
  276. backtrader/indicators/contrib/qqe_cloud_indicator.py +129 -0
  277. backtrader/indicators/contrib/ravi_indicator.py +40 -0
  278. backtrader/indicators/contrib/raw_close_close_stochastic.py +74 -0
  279. backtrader/indicators/contrib/rd_trend_trigger_indicator.py +51 -0
  280. backtrader/indicators/contrib/renko_level.py +85 -0
  281. backtrader/indicators/contrib/renko_line_break.py +91 -0
  282. backtrader/indicators/contrib/rftl_indicator.py +41 -0
  283. backtrader/indicators/contrib/rkd_indicator.py +53 -0
  284. backtrader/indicators/contrib/roc2_vg_indicator.py +68 -0
  285. backtrader/indicators/contrib/rsi_histogram_indicator.py +43 -0
  286. backtrader/indicators/contrib/rsi_slowdown.py +57 -0
  287. backtrader/indicators/contrib/rsioma_v2.py +41 -0
  288. backtrader/indicators/contrib/rvi_histogram_indicator.py +107 -0
  289. backtrader/indicators/contrib/safe_adx.py +89 -0
  290. backtrader/indicators/contrib/shared_strategy_indicators.py +1651 -0
  291. backtrader/indicators/contrib/sidus_indicator.py +105 -0
  292. backtrader/indicators/contrib/silver_trend_indicator.py +79 -0
  293. backtrader/indicators/contrib/sliding_range_color.py +56 -0
  294. backtrader/indicators/contrib/slow_stoch.py +42 -0
  295. backtrader/indicators/contrib/smoothed_adx_indicator.py +86 -0
  296. backtrader/indicators/contrib/smoothed_rsi.py +31 -0
  297. backtrader/indicators/contrib/spearman_rank_correlation_histogram.py +60 -0
  298. backtrader/indicators/contrib/stalin_indicator.py +152 -0
  299. backtrader/indicators/contrib/starter_laguerre_filter.py +62 -0
  300. backtrader/indicators/contrib/step_manrtr_indicator.py +137 -0
  301. backtrader/indicators/contrib/stochastic_histogram_indicator.py +143 -0
  302. backtrader/indicators/contrib/t3_alarm_indicator.py +125 -0
  303. backtrader/indicators/contrib/t3_average.py +76 -0
  304. backtrader/indicators/contrib/t3_indicator.py +40 -0
  305. backtrader/indicators/contrib/the20s_v020_signal.py +93 -0
  306. backtrader/indicators/contrib/three_candles_indicator.py +70 -0
  307. backtrader/indicators/contrib/three_line_break_indicator.py +64 -0
  308. backtrader/indicators/contrib/time_line.py +57 -0
  309. backtrader/indicators/contrib/trading_channel_index_proxy.py +48 -0
  310. backtrader/indicators/contrib/trend_arrows_indicator.py +109 -0
  311. backtrader/indicators/contrib/trend_continuation_indicator.py +127 -0
  312. backtrader/indicators/contrib/trend_intensity_index_proxy.py +51 -0
  313. backtrader/indicators/contrib/trend_manager_indicator.py +39 -0
  314. backtrader/indicators/contrib/tri_x_candle_indicator.py +51 -0
  315. backtrader/indicators/contrib/trigger_line.py +66 -0
  316. backtrader/indicators/contrib/triple_ema_rate.py +34 -0
  317. backtrader/indicators/contrib/trvi_indicator.py +194 -0
  318. backtrader/indicators/contrib/two_pb_ideal_xosma_indicator.py +127 -0
  319. backtrader/indicators/contrib/ultra_absolutely_no_lag_lwma_color.py +92 -0
  320. backtrader/indicators/contrib/ultra_wpr_indicator.py +173 -0
  321. backtrader/indicators/contrib/up_down_candle_strength.py +68 -0
  322. backtrader/indicators/contrib/vinin_i_trend_indicator.py +139 -0
  323. backtrader/indicators/contrib/volume_weighted_ma_indicator.py +78 -0
  324. backtrader/indicators/contrib/volume_weighted_ma_st_dev_indicator.py +111 -0
  325. backtrader/indicators/contrib/vwap_close_indicator.py +65 -0
  326. backtrader/indicators/contrib/vwma_candle.py +57 -0
  327. backtrader/indicators/contrib/vwma_digit_system.py +70 -0
  328. backtrader/indicators/contrib/wami.py +43 -0
  329. backtrader/indicators/contrib/wprsi_signal_indicator.py +105 -0
  330. backtrader/indicators/contrib/x_de_marker_histogram_vol_direct_indicator.py +145 -0
  331. backtrader/indicators/contrib/x_fisher_indicator.py +64 -0
  332. backtrader/indicators/contrib/xcci_histogram_vol_direct_indicator.py +56 -0
  333. backtrader/indicators/contrib/xcci_histogram_vol_indicator.py +85 -0
  334. backtrader/indicators/contrib/xma_ichimoku.py +163 -0
  335. backtrader/indicators/contrib/xma_ishimoku_channel_indicator.py +65 -0
  336. backtrader/indicators/contrib/xma_ishimoku_line.py +68 -0
  337. backtrader/indicators/contrib/xma_range_bands_indicator.py +107 -0
  338. backtrader/indicators/contrib/xmacd_indicator.py +70 -0
  339. backtrader/indicators/contrib/xrsi_de_marker_histogram.py +67 -0
  340. backtrader/indicators/contrib/xrsi_histogram_vol_direct_indicator.py +52 -0
  341. backtrader/indicators/contrib/xrsi_histogram_vol_indicator.py +81 -0
  342. backtrader/indicators/contrib/xrvi_indicator.py +130 -0
  343. backtrader/indicators/contrib/zero_lag_macd.py +36 -0
  344. backtrader/indicators/contrib/zig_zag_recent_pivot_signal.py +90 -0
  345. backtrader/indicators/contrib/zpf_indicator.py +115 -0
  346. backtrader/indicators/crossover.py +337 -0
  347. backtrader/indicators/dema.py +175 -0
  348. backtrader/indicators/demarker.py +270 -0
  349. backtrader/indicators/deviation.py +284 -0
  350. backtrader/indicators/directionalmove.py +1071 -0
  351. backtrader/indicators/dma.py +112 -0
  352. backtrader/indicators/dpo.py +96 -0
  353. backtrader/indicators/dv2.py +56 -0
  354. backtrader/indicators/ema.py +145 -0
  355. backtrader/indicators/envelope.py +475 -0
  356. backtrader/indicators/hadelta.py +198 -0
  357. backtrader/indicators/heikinashi.py +153 -0
  358. backtrader/indicators/hma.py +153 -0
  359. backtrader/indicators/hurst.py +151 -0
  360. backtrader/indicators/ichimoku.py +267 -0
  361. backtrader/indicators/kama.py +181 -0
  362. backtrader/indicators/kst.py +159 -0
  363. backtrader/indicators/lrsi.py +125 -0
  364. backtrader/indicators/mabase.py +147 -0
  365. backtrader/indicators/macd.py +322 -0
  366. backtrader/indicators/momentum.py +267 -0
  367. backtrader/indicators/moneyflow.py +237 -0
  368. backtrader/indicators/mt5atr.py +124 -0
  369. backtrader/indicators/myind.py +179 -0
  370. backtrader/indicators/obv.py +94 -0
  371. backtrader/indicators/ols.py +265 -0
  372. backtrader/indicators/oscillator.py +161 -0
  373. backtrader/indicators/percentchange.py +83 -0
  374. backtrader/indicators/percentrank.py +46 -0
  375. backtrader/indicators/pivotpoint.py +469 -0
  376. backtrader/indicators/prettygoodoscillator.py +113 -0
  377. backtrader/indicators/priceops_ext.py +123 -0
  378. backtrader/indicators/priceoscillator.py +262 -0
  379. backtrader/indicators/psar.py +212 -0
  380. backtrader/indicators/rmi.py +69 -0
  381. backtrader/indicators/rsi.py +440 -0
  382. backtrader/indicators/sma.py +141 -0
  383. backtrader/indicators/smma.py +116 -0
  384. backtrader/indicators/spread.py +54 -0
  385. backtrader/indicators/stochastic.py +263 -0
  386. backtrader/indicators/supertrend.py +436 -0
  387. backtrader/indicators/trend_ext.py +105 -0
  388. backtrader/indicators/trix.py +202 -0
  389. backtrader/indicators/tsi.py +155 -0
  390. backtrader/indicators/ultimateoscillator.py +158 -0
  391. backtrader/indicators/vortex.py +62 -0
  392. backtrader/indicators/williams.py +194 -0
  393. backtrader/indicators/wma.py +103 -0
  394. backtrader/indicators/zlema.py +135 -0
  395. backtrader/indicators/zlind.py +104 -0
  396. backtrader/linebuffer.py +3155 -0
  397. backtrader/lineiterator.py +2911 -0
  398. backtrader/lineroot.py +1106 -0
  399. backtrader/lineseries.py +2559 -0
  400. backtrader/live_trading/__init__.py +31 -0
  401. backtrader/live_trading/interface.py +404 -0
  402. backtrader/mathsupport.py +94 -0
  403. backtrader/metabase.py +1804 -0
  404. backtrader/mixins/__init__.py +21 -0
  405. backtrader/mixins/singleton.py +118 -0
  406. backtrader/observer.py +106 -0
  407. backtrader/observers/__init__.py +45 -0
  408. backtrader/observers/benchmark.py +126 -0
  409. backtrader/observers/broker.py +184 -0
  410. backtrader/observers/buysell.py +144 -0
  411. backtrader/observers/drawdown.py +161 -0
  412. backtrader/observers/logreturns.py +113 -0
  413. backtrader/observers/timereturn.py +86 -0
  414. backtrader/observers/trade_logger.py +2972 -0
  415. backtrader/observers/tradelogger.py +6 -0
  416. backtrader/observers/trades.py +258 -0
  417. backtrader/order.py +1114 -0
  418. backtrader/parameters.py +2345 -0
  419. backtrader/plot/__init__.py +54 -0
  420. backtrader/plot/finance.py +1022 -0
  421. backtrader/plot/formatters.py +200 -0
  422. backtrader/plot/locator.py +353 -0
  423. backtrader/plot/multicursor.py +495 -0
  424. backtrader/plot/plot.py +2500 -0
  425. backtrader/plot/plot_plotly.py +1351 -0
  426. backtrader/plot/scheme.py +253 -0
  427. backtrader/plot/utils.py +104 -0
  428. backtrader/position.py +290 -0
  429. backtrader/position_modes.py +132 -0
  430. backtrader/profiles.py +254 -0
  431. backtrader/reports/__init__.py +39 -0
  432. backtrader/reports/charts.py +371 -0
  433. backtrader/reports/performance.py +620 -0
  434. backtrader/reports/reporter.py +660 -0
  435. backtrader/resamplerfilter.py +1001 -0
  436. backtrader/signal.py +118 -0
  437. backtrader/signals/__init__.py +17 -0
  438. backtrader/sizer.py +114 -0
  439. backtrader/sizers/__init__.py +26 -0
  440. backtrader/sizers/fixedsize.py +161 -0
  441. backtrader/sizers/percents_sizer.py +119 -0
  442. backtrader/store.py +221 -0
  443. backtrader/stores/__init__.py +33 -0
  444. backtrader/stores/btapistore.py +15506 -0
  445. backtrader/stores/livestore.py +137 -0
  446. backtrader/stores/vchartfile.py +96 -0
  447. backtrader/strategy.py +3655 -0
  448. backtrader/talib.py +280 -0
  449. backtrader/test_helpers.py +96 -0
  450. backtrader/timer.py +358 -0
  451. backtrader/trade.py +442 -0
  452. backtrader/tradingcal.py +361 -0
  453. backtrader/utils/__init__.py +68 -0
  454. backtrader/utils/autodict.py +251 -0
  455. backtrader/utils/date.py +71 -0
  456. backtrader/utils/dateintern.py +509 -0
  457. backtrader/utils/flushfile.py +94 -0
  458. backtrader/utils/fractal.py +101 -0
  459. backtrader/utils/get_metrics.py +101 -0
  460. backtrader/utils/load_data.py +209 -0
  461. backtrader/utils/log_message.py +998 -0
  462. backtrader/utils/ordereddefaultdict.py +75 -0
  463. backtrader/utils/py3.py +296 -0
  464. backtrader/version.py +21 -0
  465. backtrader/writer.py +372 -0
@@ -0,0 +1,125 @@
1
+ #!/usr/bin/env python
2
+ """Laguerre RSI Module - Laguerre filter-based RSI.
3
+
4
+ This module provides the LaguerreRSI indicator defined by John F. Ehlers
5
+ for faster reaction to price changes using Laguerre filters.
6
+
7
+ Classes:
8
+ LaguerreRSI: Laguerre RSI indicator (alias: LRSI).
9
+ LaguerreFilter: Laguerre filter (alias: LAGF).
10
+
11
+ Example:
12
+ class MyStrategy(bt.Strategy):
13
+ def __init__(self):
14
+ self.lrsi = bt.indicators.LRSI(self.data, gamma=0.5)
15
+ self.lfilter = bt.indicators.LAGF(self.data, gamma=0.5)
16
+
17
+ def next(self):
18
+ if self.lrsi.lrsi[0] > 0.8:
19
+ self.sell()
20
+ elif self.lrsi.lrsi[0] < 0.2:
21
+ self.buy()
22
+ """
23
+
24
+ from . import PeriodN
25
+
26
+ __all__ = ["LaguerreRSI", "LRSI", "LaguerreFilter", "LAGF"]
27
+
28
+
29
+ class LaguerreRSI(PeriodN):
30
+ """
31
+ Defined by John F. Ehlers in `Cybernetic Analysis for Stock and Futures`,
32
+ 2004, published by Wiley. `ISBN: 978-0-471-46307-8`
33
+
34
+ The Laguerre RSI tries to implement a better RSI by providing a sort of
35
+ *Time Warp without Time Travel* using a Laguerre filter. This provides for
36
+ faster reactions to price changes
37
+
38
+ ``gamma`` is meant to have values between ``0.2`` and ``0.8``, with the
39
+ best balance found theoretically at the default of ``0.5``
40
+ """
41
+
42
+ alias = ("LRSI",)
43
+ lines = ("lrsi",)
44
+ params = (
45
+ ("gamma", 0.5),
46
+ ("period", 6),
47
+ )
48
+
49
+ plotinfo = {"plotymargin": 0.15, "plotyticks": [0.0, 0.2, 0.5, 0.8, 1.0]}
50
+
51
+ l0, l1, l2, l3 = 0.0, 0.0, 0.0, 0.0
52
+
53
+ def next(self):
54
+ """Calculate Laguerre RSI for the current bar.
55
+
56
+ Calculates L0-L3 Laguerre filter values and computes the
57
+ RSI-style ratio of upward changes to total changes.
58
+ """
59
+ l0_1 = self.l0 # cache previous intermediate values
60
+ l1_1 = self.l1
61
+ l2_1 = self.l2
62
+
63
+ g = self.p.gamma # avoid more lookups
64
+ self.l0 = l0 = (1.0 - g) * self.data + g * l0_1
65
+ self.l1 = l1 = -g * l0 + l0_1 + g * l1_1
66
+ self.l2 = l2 = -g * l1 + l1_1 + g * l2_1
67
+ self.l3 = l3 = -g * l2 + l2_1 + g * self.l3
68
+
69
+ cu = 0.0
70
+ cd = 0.0
71
+ if l0 >= l1:
72
+ cu = l0 - l1
73
+ else:
74
+ cd = l1 - l0
75
+
76
+ if l1 >= l2:
77
+ cu += l1 - l2
78
+ else:
79
+ cd += l2 - l1
80
+
81
+ if l2 >= l3:
82
+ cu += l2 - l3
83
+ else:
84
+ cd += l3 - l2
85
+
86
+ den = cu + cd
87
+ self.lines.lrsi[0] = 1.0 if not den else cu / den
88
+
89
+
90
+ class LaguerreFilter(PeriodN):
91
+ """
92
+ Defined by John F. Ehlers in `Cybernetic Analysis for Stock and Futures`,
93
+ 2004, published by Wiley. `ISBN: 978-0-471-46307-8`
94
+
95
+ ``gamma`` is meant to have values between ``0.2`` and ``0.8``, with the
96
+ best balance found theoretically at the default of ``0.5``
97
+ """
98
+
99
+ alias = ("LAGF",)
100
+ lines = ("lfilter",)
101
+ params = (("gamma", 0.5),)
102
+ plotinfo = {"subplot": False}
103
+
104
+ l0, l1, l2, l3 = 0.0, 0.0, 0.0, 0.0
105
+
106
+ def next(self):
107
+ """Calculate Laguerre filter for the current bar.
108
+
109
+ Computes L0-L3 Laguerre filter values and outputs the
110
+ weighted average (l0 + 2*l1 + 2*l2 + l3) / 6.
111
+ """
112
+ l0_1 = self.l0 # cache previous intermediate values
113
+ l1_1 = self.l1
114
+ l2_1 = self.l2
115
+
116
+ g = self.p.gamma # avoid more lookups
117
+ self.l0 = l0 = (1.0 - g) * self.data + g * l0_1
118
+ self.l1 = l1 = -g * l0 + l0_1 + g * l1_1
119
+ self.l2 = l2 = -g * l1 + l1_1 + g * l2_1
120
+ self.l3 = l3 = -g * l2 + l2_1 + g * self.l3
121
+ self.lines.lfilter[0] = (l0 + (2 * l1) + (2 * l2) + l3) / 6
122
+
123
+
124
+ LRSI = LaguerreRSI
125
+ LAGF = LaguerreFilter
@@ -0,0 +1,147 @@
1
+ #!/usr/bin/env python
2
+ """Moving Average Base Module - Core moving average infrastructure.
3
+
4
+ This module provides the base classes and registration system for all
5
+ moving average indicators in backtrader.
6
+
7
+ Classes:
8
+ MovingAverage: Placeholder for all moving average types.
9
+ MovAv: Alias for MovingAverage.
10
+ MovingAverageBase: Base class for moving average indicators.
11
+
12
+ Example:
13
+ class MyStrategy(bt.Strategy):
14
+ def __init__(self):
15
+ self.sma = bt.indicators.SMA(self.data.close, period=20)
16
+ self.ema = bt.indicators.EMA(self.data.close, period=12)
17
+ # Or using MovAv wrapper
18
+ self.wma = bt.indicators.MovAv.WMA(self.data.close, period=15)
19
+
20
+ def next(self):
21
+ if self.data.close[0] > self.sma[0]:
22
+ self.buy()
23
+ elif self.data.close[0] < self.sma[0]:
24
+ self.sell()
25
+ """
26
+
27
+ from . import Indicator
28
+
29
+
30
+ # Moving average class, used to set indicator names
31
+ class MovingAverage:
32
+ """MovingAverage (alias MovAv)
33
+
34
+ A placeholder to gather all Moving Average Types in a single place.
35
+
36
+ Instantiating a SimpleMovingAverage can be achieved as follows::
37
+
38
+ sma = MovingAverage.Simple(self.data, period)
39
+
40
+ Or using the shorter aliases::
41
+
42
+ sma = MovAv.SMA(self.data, period)
43
+
44
+ or with the full (forwards and backwards) names:
45
+
46
+ sma = MovAv.SimpleMovingAverage(self.data, period)
47
+
48
+ sma = MovAv.MovingAverageSimple(self.data, period)
49
+
50
+ """
51
+
52
+ # Storage for moving average classes
53
+ _movavs: list = []
54
+
55
+ @classmethod
56
+ def register(cls, regcls):
57
+ """Register a moving average class with the placeholder.
58
+
59
+ Args:
60
+ regcls: The moving average class to register.
61
+
62
+ Sets the class name and aliases as attributes on the placeholder
63
+ for easy access (e.g., MovAv.SMA, MovAv.EMA).
64
+ """
65
+ # If indicator doesn't have _notregister or _notregister value is False, continue to register, otherwise return directly
66
+ if getattr(regcls, "_notregister", False):
67
+ return
68
+ # Add indicator class to be calculated
69
+ cls._movavs.append(regcls)
70
+ # Class name, and set class name as cls attribute, attribute value is the specific class
71
+ clsname = regcls.__name__
72
+ setattr(cls, clsname, regcls)
73
+
74
+ # Specific indicator alias, if indicator starts with MovingAverage, use latter value as alias, if ends with MovingAverage, use former value as alias
75
+ # If obtained alias is not empty string, then also set alias as attribute, attribute value is this class
76
+ clsalias = ""
77
+ if clsname.endswith("MovingAverage"):
78
+ clsalias = clsname.split("MovingAverage")[0]
79
+ elif clsname.startswith("MovingAverage"):
80
+ clsalias = clsname.split("MovingAverage")[1]
81
+
82
+ if clsalias:
83
+ setattr(cls, clsalias, regcls)
84
+
85
+ # CRITICAL FIX: Process the alias attribute if it exists
86
+ # Many indicators define their own aliases like alias = ("SMA", "SimpleMovingAverage")
87
+ if hasattr(regcls, "alias"):
88
+ aliases = regcls.alias
89
+ # Support both tuple and single string
90
+ if isinstance(aliases, str):
91
+ aliases = (aliases,)
92
+ # Register each alias
93
+ for alias_name in aliases:
94
+ if alias_name and isinstance(alias_name, str):
95
+ setattr(cls, alias_name, regcls)
96
+
97
+
98
+ # Alias for moving average
99
+ class MovAv(MovingAverage):
100
+ """Alias for MovingAverage.
101
+
102
+ Provides a shorter name for accessing moving average types.
103
+ """
104
+
105
+ # alias
106
+
107
+
108
+ # Base class for moving average, add parameters and plot settings - refactored to remove metaclass
109
+ class MovingAverageBase(Indicator):
110
+ """Base class for all moving average indicators.
111
+
112
+ Provides common initialization with minimum period management and
113
+ automatic registration with the MovingAverage placeholder.
114
+
115
+ Attributes:
116
+ params: Default period parameter (30).
117
+ plotinfo: Default to plot on main chart (subplot=False).
118
+ """
119
+
120
+ # Parameters
121
+ params = (("period", 30),)
122
+ # Plot on main chart by default
123
+ plotinfo = {"subplot": False}
124
+
125
+ def __init__(self):
126
+ """Initialize moving average and set minimum period"""
127
+ super().__init__()
128
+
129
+ # CRITICAL FIX: Inherit minperiod from data source BEFORE adding own period
130
+ # This ensures nested indicators (like EMA applied to MACD line) properly accumulate minperiods
131
+ if hasattr(self, "datas") and self.datas:
132
+ data_minperiods = [getattr(d, "_minperiod", 1) for d in self.datas if d is not None]
133
+ if data_minperiods:
134
+ data_max = max(data_minperiods)
135
+ if data_max > self._minperiod:
136
+ self._minperiod = data_max
137
+
138
+ # CRITICAL FIX: Set the minimum period based on the period parameter
139
+ # This ensures the indicator doesn't start calculating until enough data is available
140
+ self.addminperiod(self.p.period)
141
+
142
+ def __init_subclass__(cls, **kwargs):
143
+ """Register moving average classes automatically"""
144
+ super().__init_subclass__(**kwargs)
145
+ # Register any MovingAverage with the placeholder to allow the automatic
146
+ # creation of envelopes and oscillators
147
+ MovingAverage.register(cls)
@@ -0,0 +1,322 @@
1
+ #!/usr/bin/env python
2
+ """MACD Indicator Module - Moving Average Convergence Divergence.
3
+
4
+ This module provides the MACD (Moving Average Convergence Divergence)
5
+ indicator developed by Gerald Appel in the 1970s for trend following.
6
+
7
+ Classes:
8
+ MACD: MACD indicator with signal line.
9
+ MACDHisto: MACD with histogram (alias: MACDHistogram).
10
+
11
+ Example:
12
+ class MyStrategy(bt.Strategy):
13
+ def __init__(self):
14
+ self.macd = bt.indicators.MACD(self.data)
15
+ self.macd_hist = bt.indicators.MACDHisto(self.data)
16
+
17
+ def next(self):
18
+ # MACD crossover strategy
19
+ if self.macd.macd[0] > self.macd.signal[0]:
20
+ self.buy()
21
+ elif self.macd.macd[0] < self.macd.signal[0]:
22
+ self.sell()
23
+ """
24
+
25
+ import math
26
+
27
+ from . import Indicator, MovAv
28
+
29
+
30
+ def _finite(value):
31
+ return value is not None and not (isinstance(value, float) and not math.isfinite(value))
32
+
33
+
34
+ class MACD(Indicator):
35
+ """
36
+ Moving Average Convergence Divergence. Defined by Gerald Appel in the 70s.
37
+
38
+ It measures the distance of a short and a long term moving average to
39
+ try to identify the trend.
40
+
41
+ A second lagging moving average over the convergence-divergence should
42
+ provide a "signal" upon being crossed by the macd
43
+
44
+ Formula:
45
+ - macd = ema(data, me1_period) - ema(data, me2_period)
46
+ - signal = ema(macd, signal_period)
47
+
48
+ See:
49
+ - http://en.wikipedia.org/wiki/MACD
50
+ """
51
+
52
+ lines = (
53
+ "macd",
54
+ "signal",
55
+ )
56
+ params = (
57
+ ("period_me1", 12),
58
+ ("period_me2", 26),
59
+ ("period_signal", 9),
60
+ ("movav", MovAv.Exponential),
61
+ )
62
+
63
+ plotinfo = {"plothlines": [0.0]}
64
+ plotlines = {"signal": {"ls": "--"}}
65
+
66
+ def _plotlabel(self):
67
+ plabels = super()._plotlabel()
68
+ if self.p.isdefault("movav"):
69
+ plabels.remove(self.p.movav)
70
+ return plabels
71
+
72
+ def __init__(self):
73
+ """Initialize the MACD indicator.
74
+
75
+ Creates moving averages and sets up signal line calculation.
76
+ """
77
+ super().__init__()
78
+ # Store the EMAs as sub-indicators
79
+ self.me1 = self.p.movav(self.data, period=self.p.period_me1)
80
+ self.me2 = self.p.movav(self.data, period=self.p.period_me2)
81
+ # Preserve master's aliases without adding extra indicator output lines.
82
+ self.lines.me1 = self.me1
83
+ self.lines.me2 = self.me2
84
+
85
+ # Calculate minperiod
86
+ self.macd_minperiod = max(self.p.period_me1, self.p.period_me2)
87
+ signal_minperiod = self.macd_minperiod + self.p.period_signal - 1
88
+ self._minperiod = max(self._minperiod, signal_minperiod)
89
+
90
+ # CRITICAL FIX: Propagate minperiod to lines so that other indicators
91
+ # using these lines as data sources will inherit the correct minperiod
92
+ for line in self.lines:
93
+ line.updateminperiod(self._minperiod)
94
+
95
+ # Signal line alpha for EMA calculation
96
+ self.signal_alpha = 2.0 / (1.0 + self.p.period_signal)
97
+ self.signal_alpha1 = 1.0 - self.signal_alpha
98
+
99
+ def prenext(self):
100
+ """Calculate MACD during warmup period.
101
+
102
+ Ensures MACD values are available for signal line seeding.
103
+ """
104
+ try:
105
+ me1_val = self.me1[0]
106
+ me2_val = self.me2[0]
107
+ except (IndexError, TypeError):
108
+ self.lines.macd[0] = float("nan")
109
+ return
110
+
111
+ if not (_finite(me1_val) and _finite(me2_val)):
112
+ self.lines.macd[0] = float("nan")
113
+ return
114
+
115
+ self.lines.macd[0] = me1_val - me2_val
116
+
117
+ def nextstart(self):
118
+ """Calculate MACD and seed signal line on first valid bar.
119
+
120
+ Computes MACD and seeds signal with SMA of MACD values.
121
+ """
122
+ try:
123
+ me1_val = self.me1[0]
124
+ me2_val = self.me2[0]
125
+ except (IndexError, TypeError):
126
+ self.lines.macd[0] = float("nan")
127
+ self.lines.signal[0] = float("nan")
128
+ return
129
+
130
+ if not (_finite(me1_val) and _finite(me2_val)):
131
+ self.lines.macd[0] = float("nan")
132
+ self.lines.signal[0] = float("nan")
133
+ return
134
+
135
+ macd_val = me1_val - me2_val
136
+ self.lines.macd[0] = macd_val
137
+ # # Seed signal with MACD value
138
+ # self.lines.signal[0] = macd_val
139
+ signal_period = self.p.period_signal
140
+ macd_sum = 0.0
141
+ macd_count = 0
142
+ for i in range(signal_period):
143
+ try:
144
+ value = self.lines.macd[-i]
145
+ except (IndexError, TypeError):
146
+ value = float("nan")
147
+ if _finite(value):
148
+ macd_sum += value
149
+ macd_count += 1
150
+ self.lines.signal[0] = macd_sum / macd_count if macd_count else macd_val
151
+
152
+ def next(self):
153
+ """Calculate MACD and signal line for the current bar.
154
+
155
+ MACD = me1 - me2
156
+ Signal = EMA(MACD)
157
+ """
158
+ try:
159
+ me1_val = self.me1[0]
160
+ me2_val = self.me2[0]
161
+ except (IndexError, TypeError):
162
+ self.lines.macd[0] = float("nan")
163
+ self.lines.signal[0] = float("nan")
164
+ return
165
+
166
+ if not (_finite(me1_val) and _finite(me2_val)):
167
+ self.lines.macd[0] = float("nan")
168
+ self.lines.signal[0] = float("nan")
169
+ return
170
+
171
+ macd_val = me1_val - me2_val
172
+ self.lines.macd[0] = macd_val
173
+ # Calculate signal = EMA of MACD
174
+ try:
175
+ previous_signal = self.lines.signal[-1]
176
+ except (IndexError, TypeError):
177
+ previous_signal = macd_val
178
+
179
+ if not _finite(previous_signal):
180
+ previous_signal = macd_val
181
+
182
+ self.lines.signal[0] = previous_signal * self.signal_alpha1 + macd_val * self.signal_alpha
183
+
184
+ def once(self, start, end):
185
+ """Calculate MACD in runonce mode"""
186
+ me1_array = self.me1.lines[0].array
187
+ me2_array = self.me2.lines[0].array
188
+ macd_array = self.lines.macd.array
189
+ signal_array = self.lines.signal.array
190
+
191
+ signal_alpha = self.signal_alpha
192
+ signal_alpha1 = self.signal_alpha1
193
+ macd_minperiod = self.macd_minperiod
194
+ signal_period = self.p.period_signal
195
+
196
+ # Ensure arrays are properly sized
197
+ while len(macd_array) < end:
198
+ macd_array.append(float("nan"))
199
+ while len(signal_array) < end:
200
+ signal_array.append(float("nan"))
201
+
202
+ # Pre-fill warmup period with NaN
203
+ for i in range(min(macd_minperiod - 1, len(me1_array))):
204
+ macd_array[i] = float("nan")
205
+ signal_array[i] = float("nan")
206
+
207
+ # Calculate MACD values for all data points from macd_minperiod onwards
208
+ for i in range(macd_minperiod - 1, min(end, len(me1_array), len(me2_array))):
209
+ me1_val = me1_array[i]
210
+ me2_val = me2_array[i]
211
+
212
+ # Handle NaN values
213
+ if isinstance(me1_val, float) and math.isnan(me1_val):
214
+ macd_array[i] = float("nan")
215
+ continue
216
+ if isinstance(me2_val, float) and math.isnan(me2_val):
217
+ macd_array[i] = float("nan")
218
+ continue
219
+
220
+ macd_array[i] = me1_val - me2_val
221
+
222
+ # Calculate signal line (EMA of MACD)
223
+ signal_start = macd_minperiod + signal_period - 2
224
+
225
+ # Pre-fill signal warmup with NaN
226
+ for i in range(macd_minperiod - 1, min(signal_start, len(signal_array))):
227
+ signal_array[i] = float("nan")
228
+
229
+ # Seed signal with SMA of first signal_period MACD values
230
+ if signal_start < len(macd_array) and signal_start >= 0:
231
+ seed_sum = 0.0
232
+ seed_count = 0
233
+ for j in range(macd_minperiod - 1, signal_start + 1):
234
+ if j < len(macd_array):
235
+ val = macd_array[j]
236
+ if not (isinstance(val, float) and math.isnan(val)):
237
+ seed_sum += val
238
+ seed_count += 1
239
+ prev_signal = seed_sum / seed_count if seed_count > 0 else 0.0
240
+ signal_array[signal_start] = prev_signal
241
+ else:
242
+ prev_signal = 0.0
243
+
244
+ # Calculate signal EMA for all subsequent data points
245
+ for i in range(signal_start + 1, min(end, len(macd_array))):
246
+ macd_val = macd_array[i]
247
+ if isinstance(macd_val, float) and math.isnan(macd_val):
248
+ signal_array[i] = float("nan")
249
+ continue
250
+
251
+ prev_signal = prev_signal * signal_alpha1 + macd_val * signal_alpha
252
+ signal_array[i] = prev_signal
253
+
254
+
255
+ class MACDHisto(MACD):
256
+ """
257
+ Subclass of MACD which adds a "histogram" of the difference between the
258
+ macd and signal lines
259
+
260
+ Formula:
261
+ - histo = macd - signal
262
+
263
+ See:
264
+ - http://en.wikipedia.org/wiki/MACD
265
+ """
266
+
267
+ alias = ("MACDHistogram",)
268
+
269
+ lines = ("histo",)
270
+ plotlines = {"histo": {"_method": "bar", "alpha": 0.50, "width": 1.0}}
271
+
272
+ def __init__(self):
273
+ """Initialize the MACD Histogram indicator.
274
+
275
+ Extends MACD with histogram line.
276
+ """
277
+ super().__init__()
278
+
279
+ def nextstart(self):
280
+ """Calculate MACD Histogram on first valid bar.
281
+
282
+ Histogram = MACD - Signal.
283
+ """
284
+ super().nextstart()
285
+ self.lines.histo[0] = self.lines.macd[0] - self.lines.signal[0]
286
+
287
+ def next(self):
288
+ """Calculate MACD Histogram for the current bar.
289
+
290
+ Histogram = MACD - Signal.
291
+ """
292
+ super().next()
293
+ self.lines.histo[0] = self.lines.macd[0] - self.lines.signal[0]
294
+
295
+ def once(self, start, end):
296
+ """Calculate MACD Histogram in runonce mode.
297
+
298
+ Computes histogram as MACD minus signal across all bars.
299
+ """
300
+ super().once(start, end)
301
+ macd_array = self.lines.macd.array
302
+ signal_array = self.lines.signal.array
303
+ histo_array = self.lines.histo.array
304
+
305
+ # Ensure histo array is sized
306
+ while len(histo_array) < end:
307
+ histo_array.append(float("nan"))
308
+
309
+ # Calculate histogram
310
+ for i in range(start, min(end, len(macd_array), len(signal_array))):
311
+ macd_val = macd_array[i] if i < len(macd_array) else 0.0
312
+ signal_val = signal_array[i] if i < len(signal_array) else 0.0
313
+
314
+ if (
315
+ isinstance(macd_val, float)
316
+ and math.isnan(macd_val)
317
+ or isinstance(signal_val, float)
318
+ and math.isnan(signal_val)
319
+ ):
320
+ histo_array[i] = float("nan")
321
+ else:
322
+ histo_array[i] = macd_val - signal_val