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,1022 @@
1
+ #!/usr/bin/env python
2
+ """Financial plotting utilities for backtrader.
3
+
4
+ This module provides plot handlers and functions for rendering various
5
+ financial chart types including candlestick, OHLC, volume, and line-on-close
6
+ plots using matplotlib.
7
+ """
8
+
9
+ import matplotlib.collections as mcol
10
+ import matplotlib.colors as mcolors
11
+ import matplotlib.legend as mlegend
12
+ import matplotlib.lines as mlines
13
+
14
+ from ..utils.py3 import range, zip
15
+ from .utils import shade_color
16
+
17
+
18
+ class CandlestickPlotHandler:
19
+ """Handler for creating and managing candlestick plot collections.
20
+
21
+ This class creates matplotlib collections for rendering candlestick charts
22
+ with customizable colors for up and down bars. It also provides custom
23
+ legend rendering for candlestick patterns.
24
+
25
+ Attributes:
26
+ legend_opens: Open prices for legend sample candles.
27
+ legend_highs: High prices for legend sample candles.
28
+ legend_lows: Low prices for legend sample candles.
29
+ legend_closes: Close prices for legend sample candles.
30
+ colorup: RGBA color for up bars (close > open).
31
+ colordown: RGBA color for down bars (close < open).
32
+ edgeup: RGBA edge color for up bars.
33
+ edgedown: RGBA edge color for down bars.
34
+ tickup: RGBA color for up tick marks.
35
+ tickdown: RGBA color for down tick marks.
36
+ barcol: PolyCollection containing the candlestick bodies.
37
+ tickcol: LineCollection containing the candlestick wicks.
38
+ """
39
+
40
+ legend_opens = [0.50, 0.50, 0.50]
41
+ legend_highs = [1.00, 1.00, 1.00]
42
+ legend_lows = [0.00, 0.00, 0.00]
43
+ legend_closes = [0.80, 0.00, 1.00]
44
+
45
+ def __init__(
46
+ self,
47
+ ax,
48
+ x,
49
+ opens,
50
+ highs,
51
+ lows,
52
+ closes,
53
+ colorup="k",
54
+ colordown="r",
55
+ edgeup=None,
56
+ edgedown=None,
57
+ tickup=None,
58
+ tickdown=None,
59
+ width=1,
60
+ tickwidth=1,
61
+ edgeadjust=0.05,
62
+ edgeshading=-10,
63
+ alpha=1.0,
64
+ label="_nolegend",
65
+ fillup=True,
66
+ filldown=True,
67
+ **kwargs,
68
+ ):
69
+ """Initialize the candlestick plot handler.
70
+
71
+ Args:
72
+ ax: Matplotlib axes object to add collections to.
73
+ x: Array of x-axis coordinates (typically bar indices).
74
+ opens: Array of opening prices.
75
+ highs: Array of high prices.
76
+ lows: Array of low prices.
77
+ closes: Array of closing prices.
78
+ colorup: Color for up bars (close > open). Default is "k" (black).
79
+ colordown: Color for down bars (close < open). Default is "r" (red).
80
+ edgeup: Edge color for up bars. If None, derived from colorup with shading.
81
+ edgedown: Edge color for down bars. If None, derived from colordown with shading.
82
+ tickup: Color for up tick marks (wicks). If None, uses edgeup.
83
+ tickdown: Color for down tick marks (wicks). If None, uses edgedown.
84
+ width: Width of candlestick bodies. Default is 1.
85
+ tickwidth: Width of candlestick wicks. Default is 1.
86
+ edgeadjust: Adjustment for edge width. Default is 0.05.
87
+ edgeshading: Shading factor for edge colors. Default is -10.
88
+ alpha: Transparency level (0-1). Default is 1.0.
89
+ label: Label for legend. Default is "_nolegend".
90
+ fillup: Whether to fill up bars. Default is True.
91
+ filldown: Whether to fill down bars. Default is True.
92
+ **kwargs: Additional keyword arguments passed to collections.
93
+
94
+ Raises:
95
+ ValueError: If color conversion fails.
96
+ """
97
+ # Manager up/down bar colors
98
+ r, g, b = mcolors.colorConverter.to_rgb(colorup)
99
+ self.colorup = r, g, b, alpha
100
+ r, g, b = mcolors.colorConverter.to_rgb(colordown)
101
+ self.colordown = r, g, b, alpha
102
+ # Manage the edge up/down colors for the bars
103
+ if edgeup:
104
+ r, g, b = mcolors.colorConverter.to_rgb(edgeup)
105
+ self.edgeup = ((r, g, b, alpha),)
106
+ else:
107
+ self.edgeup = shade_color(self.colorup, edgeshading)
108
+
109
+ if edgedown:
110
+ r, g, b = mcolors.colorConverter.to_rgb(edgedown)
111
+ self.edgedown = ((r, g, b, alpha),)
112
+ else:
113
+ self.edgedown = shade_color(self.colordown, edgeshading)
114
+
115
+ # Manage the up/down tick colors
116
+ if tickup:
117
+ r, g, b = mcolors.colorConverter.to_rgb(tickup)
118
+ self.tickup = ((r, g, b, alpha),)
119
+ else:
120
+ self.tickup = self.edgeup
121
+
122
+ if tickdown:
123
+ r, g, b = mcolors.colorConverter.to_rgb(tickdown)
124
+ self.tickdown = ((r, g, b, alpha),)
125
+ else:
126
+ self.tickdown = self.edgedown
127
+
128
+ self.barcol, self.tickcol = self.barcollection(
129
+ x,
130
+ opens,
131
+ highs,
132
+ lows,
133
+ closes,
134
+ width,
135
+ tickwidth,
136
+ edgeadjust,
137
+ label=label,
138
+ fillup=fillup,
139
+ filldown=filldown,
140
+ **kwargs,
141
+ )
142
+
143
+ # add collections to the axis and return them
144
+ ax.add_collection(self.tickcol)
145
+ ax.add_collection(self.barcol)
146
+
147
+ # Update the axis
148
+ ax.update_datalim(((0, min(lows)), (len(opens), max(highs))))
149
+ ax.autoscale_view()
150
+
151
+ # Add self as legend handler for this object
152
+ mlegend.Legend.update_default_handler_map({self.barcol: self})
153
+
154
+ def legend_artist(self, legend, orig_handle, fontsize, handlebox):
155
+ """Create a custom legend artist for candlestick plots.
156
+
157
+ Args:
158
+ legend: The legend object being created.
159
+ orig_handle: The original handle for which the artist is created.
160
+ fontsize: The font size for the legend.
161
+ handlebox: The handlebox container for positioning the legend artist.
162
+
163
+ Returns:
164
+ Tuple of (barcol, tickcol): The bar and tick collections for the legend.
165
+ """
166
+ x0 = handlebox.xdescent
167
+ y0 = handlebox.ydescent
168
+ width = handlebox.width / len(self.legend_opens)
169
+ height = handlebox.height
170
+
171
+ # Generate the x-axis coordinates (handlebox based)
172
+ xs = [x0 + width * (i + 0.5) for i in range(len(self.legend_opens))]
173
+
174
+ barcol, tickcol = self.barcollection(
175
+ xs,
176
+ self.legend_opens,
177
+ self.legend_highs,
178
+ self.legend_lows,
179
+ self.legend_closes,
180
+ width=width,
181
+ tickwidth=2,
182
+ scaling=height,
183
+ bot=y0,
184
+ )
185
+
186
+ barcol.set_transform(handlebox.get_transform())
187
+ handlebox.add_artist(barcol)
188
+ tickcol.set_transform(handlebox.get_transform())
189
+ handlebox.add_artist(tickcol)
190
+
191
+ return barcol, tickcol
192
+
193
+ def barcollection(
194
+ self,
195
+ xs,
196
+ opens,
197
+ highs,
198
+ lows,
199
+ closes,
200
+ width,
201
+ tickwidth=1,
202
+ edgeadjust=0,
203
+ label="_nolegend",
204
+ scaling=1.0,
205
+ bot=0,
206
+ fillup=True,
207
+ filldown=True,
208
+ **kwargs,
209
+ ):
210
+ """Create matplotlib collections for candlestick bars and wicks.
211
+
212
+ Args:
213
+ xs: Array of x-axis coordinates.
214
+ opens: Array of opening prices.
215
+ highs: Array of high prices.
216
+ lows: Array of low prices.
217
+ closes: Array of closing prices.
218
+ width: Width of candlestick bodies.
219
+ tickwidth: Width of candlestick wicks. Default is 1.
220
+ edgeadjust: Adjustment for edge width. Default is 0.
221
+ label: Label for legend. Default is "_nolegend".
222
+ scaling: Vertical scaling factor. Default is 1.0.
223
+ bot: Bottom offset for vertical positioning. Default is 0.
224
+ fillup: Whether to fill up bars. Default is True.
225
+ filldown: Whether to fill down bars. Default is True.
226
+ **kwargs: Additional keyword arguments passed to collections.
227
+
228
+ Returns:
229
+ Tuple of (barcol, tickcol): PolyCollection for bodies and LineCollection for wicks.
230
+ """
231
+ # Prepack different zips of the series values
232
+ oc = lambda: zip(opens, closes) # NOQA: E731
233
+ xoc = lambda: zip(xs, opens, closes) # NOQA: E731
234
+ iohlc = lambda: zip(xs, opens, highs, lows, closes) # NOQA: E731
235
+
236
+ colorup = self.colorup if fillup else "None"
237
+ colordown = self.colordown if filldown else "None"
238
+ colord = {True: colorup, False: colordown}
239
+ colors = [colord[o < c] for o, c in oc()]
240
+
241
+ edgecolord = {True: self.edgeup, False: self.edgedown}
242
+ edgecolors = [edgecolord[o < c] for o, c in oc()]
243
+
244
+ tickcolord = {True: self.tickup, False: self.tickdown}
245
+ tickcolors = [tickcolord[o < c] for o, c in oc()]
246
+
247
+ delta = width / 2 - edgeadjust
248
+
249
+ def barbox(i, open_, close):
250
+ # delta seen as closure
251
+ left, right = i - delta, i + delta
252
+ open_ = open_ * scaling + bot
253
+ close = close * scaling + bot
254
+ return (left, open_), (left, close), (right, close), (right, open_)
255
+
256
+ barareas = [barbox(i, o, c) for i, o, c in xoc()]
257
+
258
+ def tup(i, open_, high, close):
259
+ high = high * scaling + bot
260
+ open_ = open_ * scaling + bot
261
+ close = close * scaling + bot
262
+
263
+ return (i, high), (i, max(open_, close))
264
+
265
+ tickrangesup = [tup(i, o, h, c) for i, o, h, low, c in iohlc()]
266
+
267
+ def tdown(i, open_, low, close):
268
+ low = low * scaling + bot
269
+ open_ = open_ * scaling + bot
270
+ close = close * scaling + bot
271
+
272
+ return (i, low), (i, min(open_, close))
273
+
274
+ tickrangesdown = [tdown(i, o, low, c) for i, o, h, low, c in iohlc()]
275
+
276
+ # Extra variables for the collections
277
+ useaa = (0,) # use tuple here
278
+ lw = (0.5,) # and here
279
+ tlw = (tickwidth,)
280
+
281
+ # Bar collection for the candles
282
+ barcol = mcol.PolyCollection(
283
+ barareas,
284
+ facecolors=colors,
285
+ edgecolors=edgecolors,
286
+ antialiaseds=useaa,
287
+ linewidths=lw,
288
+ label=label,
289
+ **kwargs,
290
+ )
291
+
292
+ # LineCollections have a higher zorder than PolyCollections
293
+ # to ensure the edges of the bars are not overwriten by the Lines
294
+ # we need to put the bars slightly over the LineCollections
295
+ kwargs["zorder"] = barcol.get_zorder() * 0.9999
296
+
297
+ # Up/down ticks from the body
298
+ tickcol = mcol.LineCollection(
299
+ tickrangesup + tickrangesdown,
300
+ colors=tickcolors,
301
+ linewidths=tlw,
302
+ antialiaseds=useaa,
303
+ **kwargs,
304
+ )
305
+
306
+ # return barcol, tickcol
307
+ return barcol, tickcol
308
+
309
+
310
+ def plot_candlestick(
311
+ ax,
312
+ x,
313
+ opens,
314
+ highs,
315
+ lows,
316
+ closes,
317
+ colorup="k",
318
+ colordown="r",
319
+ edgeup=None,
320
+ edgedown=None,
321
+ tickup=None,
322
+ tickdown=None,
323
+ width=1,
324
+ tickwidth=1.25,
325
+ edgeadjust=0.05,
326
+ edgeshading=-10,
327
+ alpha=1.0,
328
+ label="_nolegend",
329
+ fillup=True,
330
+ filldown=True,
331
+ **kwargs,
332
+ ):
333
+ """Plot candlestick chart on given axes.
334
+
335
+ Convenience function that creates a CandlestickPlotHandler and returns
336
+ the matplotlib collections for the candlestick chart.
337
+
338
+ Args:
339
+ ax: Matplotlib axes object to add collections to.
340
+ x: Array of x-axis coordinates (typically bar indices).
341
+ opens: Array of opening prices.
342
+ highs: Array of high prices.
343
+ lows: Array of low prices.
344
+ closes: Array of closing prices.
345
+ colorup: Color for up bars (close > open). Default is "k" (black).
346
+ colordown: Color for down bars (close < open). Default is "r" (red).
347
+ edgeup: Edge color for up bars. If None, derived from colorup with shading.
348
+ edgedown: Edge color for down bars. If None, derived from colordown with shading.
349
+ tickup: Color for up tick marks (wicks). If None, uses edgeup.
350
+ tickdown: Color for down tick marks (wicks). If None, uses edgedown.
351
+ width: Width of candlestick bodies. Default is 1.
352
+ tickwidth: Width of candlestick wicks. Default is 1.25.
353
+ edgeadjust: Adjustment for edge width. Default is 0.05.
354
+ edgeshading: Shading factor for edge colors. Default is -10.
355
+ alpha: Transparency level (0-1). Default is 1.0.
356
+ label: Label for legend. Default is "_nolegend".
357
+ fillup: Whether to fill up bars. Default is True.
358
+ filldown: Whether to fill down bars. Default is True.
359
+ **kwargs: Additional keyword arguments passed to collections.
360
+
361
+ Returns:
362
+ Tuple of (barcol, tickcol): PolyCollection for bodies and LineCollection for wicks.
363
+ """
364
+ chandler = CandlestickPlotHandler(
365
+ ax,
366
+ x,
367
+ opens,
368
+ highs,
369
+ lows,
370
+ closes,
371
+ colorup,
372
+ colordown,
373
+ edgeup,
374
+ edgedown,
375
+ tickup,
376
+ tickdown,
377
+ width,
378
+ tickwidth,
379
+ edgeadjust,
380
+ edgeshading,
381
+ alpha,
382
+ label,
383
+ fillup,
384
+ filldown,
385
+ **kwargs,
386
+ )
387
+
388
+ # Return the collections.
389
+ # The barcol goes first because it
390
+ # is the larger, has the dominant zorder and defines the legend
391
+ return chandler.barcol, chandler.tickcol
392
+
393
+
394
+ class VolumePlotHandler:
395
+ """Handler for creating and managing volume plot collections.
396
+
397
+ This class creates matplotlib collections for rendering volume bars
398
+ with customizable colors for up and down periods based on price movement.
399
+
400
+ Attributes:
401
+ legend_vols: Sample volumes for legend rendering.
402
+ legend_opens: Sample open prices for legend rendering.
403
+ legend_closes: Sample close prices for legend rendering.
404
+ colorup: RGBA color for up volume bars (close > open).
405
+ colordown: RGBA color for down volume bars (close < open).
406
+ edgeup: RGBA edge color for up bars.
407
+ edgedown: RGBA edge color for down bars.
408
+ barcol: PolyCollection containing the volume bars.
409
+ """
410
+
411
+ legend_vols = [0.5, 1.0, 0.75]
412
+ legend_opens = [0, 1, 0]
413
+ legend_closes = [1, 0, 1]
414
+
415
+ def __init__(
416
+ self,
417
+ ax,
418
+ x,
419
+ opens,
420
+ closes,
421
+ volumes,
422
+ colorup="k",
423
+ colordown="r",
424
+ edgeup=None,
425
+ edgedown=None,
426
+ edgeshading=-5,
427
+ edgeadjust=0.05,
428
+ width=1,
429
+ alpha=1.0,
430
+ **kwargs,
431
+ ):
432
+ """Initialize the volume plot handler.
433
+
434
+ Args:
435
+ ax: Matplotlib axes object to add collections to.
436
+ x: Array of x-axis coordinates (typically bar indices).
437
+ opens: Array of opening prices.
438
+ closes: Array of closing prices.
439
+ volumes: Array of volume values.
440
+ colorup: Color for up volume bars (close > open). Default is "k" (black).
441
+ colordown: Color for down volume bars (close < open). Default is "r" (red).
442
+ edgeup: Edge color for up bars. If None, derived from colorup with shading.
443
+ edgedown: Edge color for down bars. If None, derived from colordown with shading.
444
+ edgeshading: Shading factor for edge colors. Default is -5.
445
+ edgeadjust: Adjustment for edge width. Default is 0.05.
446
+ width: Width of volume bars. Default is 1.
447
+ alpha: Transparency level (0-1). Default is 1.0.
448
+ **kwargs: Additional keyword arguments passed to collections.
449
+
450
+ Raises:
451
+ ValueError: If color conversion fails.
452
+ """
453
+ # Manage the up/down colors
454
+ r, g, b = mcolors.colorConverter.to_rgb(colorup)
455
+ self.colorup = r, g, b, alpha
456
+ r, g, b = mcolors.colorConverter.to_rgb(colordown)
457
+ self.colordown = r, g, b, alpha
458
+
459
+ # Prepare the edge colors
460
+ if not edgeup:
461
+ self.edgeup = shade_color(self.colorup, edgeshading)
462
+ else:
463
+ r, g, b = mcolors.colorConverter.to_rgb(edgeup)
464
+ self.edgeup = r, g, b, alpha
465
+
466
+ if not edgedown:
467
+ self.edgedown = shade_color(self.colordown, edgeshading)
468
+ else:
469
+ r, g, b = mcolors.colorConverter.to_rgb(edgedown)
470
+ self.edgedown = r, g, b, alpha
471
+
472
+ corners = (0, 0), (len(closes), max(volumes))
473
+ ax.update_datalim(corners)
474
+ ax.autoscale_view()
475
+
476
+ self.barcol = self.barcollection(
477
+ x, opens, closes, volumes, width=width, edgeadjust=edgeadjust, **kwargs
478
+ )
479
+
480
+ # add to axes
481
+ ax.add_collection(self.barcol)
482
+
483
+ # Add a legend handler for this object
484
+ mlegend.Legend.update_default_handler_map({self.barcol: self})
485
+
486
+ def legend_artist(self, legend, orig_handle, fontsize, handlebox):
487
+ """Create a custom legend artist for volume plots.
488
+
489
+ Args:
490
+ legend: The legend object being created.
491
+ orig_handle: The original handle for which the artist is created.
492
+ fontsize: The font size for the legend.
493
+ handlebox: The handlebox container for positioning the legend artist.
494
+
495
+ Returns:
496
+ barcol: The volume bar collection for the legend.
497
+ """
498
+ x0 = handlebox.xdescent
499
+ y0 = handlebox.ydescent
500
+ width = handlebox.width / len(self.legend_vols)
501
+ height = handlebox.height
502
+
503
+ # Generate the x-axis coordinates (handlebox based)
504
+ xs = [x0 + width * (i + 0.5) for i in range(len(self.legend_vols))]
505
+
506
+ barcol = self.barcollection(
507
+ xs,
508
+ self.legend_opens,
509
+ self.legend_closes,
510
+ self.legend_vols,
511
+ width=width,
512
+ vscaling=height,
513
+ vbot=y0,
514
+ )
515
+
516
+ barcol.set_transform(handlebox.get_transform())
517
+ handlebox.add_artist(barcol)
518
+
519
+ return barcol
520
+
521
+ def barcollection(
522
+ self, x, opens, closes, vols, width, edgeadjust=0, vscaling=1.0, vbot=0, **kwargs
523
+ ):
524
+ """Create matplotlib collection for volume bars.
525
+
526
+ Args:
527
+ x: Array of x-axis coordinates.
528
+ opens: Array of opening prices.
529
+ closes: Array of closing prices.
530
+ vols: Array of volume values.
531
+ width: Width of volume bars.
532
+ edgeadjust: Adjustment for edge width. Default is 0.
533
+ vscaling: Vertical scaling factor. Default is 1.0.
534
+ vbot: Bottom offset for vertical positioning. Default is 0.
535
+ **kwargs: Additional keyword arguments passed to collection.
536
+
537
+ Returns:
538
+ barcol: PolyCollection containing the volume bars.
539
+ """
540
+ # Prepare the data
541
+ openclose = lambda: zip(opens, closes) # NOQA: E731
542
+
543
+ # Calculate bars colors
544
+ colord = {True: self.colorup, False: self.colordown}
545
+ colors = [colord[open_ < close] for open_, close in openclose()]
546
+ edgecolord = {True: self.edgeup, False: self.edgedown}
547
+ edgecolors = [edgecolord[open_ < close] for open_, close in openclose()]
548
+
549
+ # bar width to the sides
550
+ delta = width / 2 - edgeadjust
551
+
552
+ # small auxiliary func to return the bar coordinates
553
+ def volbar(i, v):
554
+ left, right = i - delta, i + delta
555
+ v = vbot + v * vscaling
556
+ return (left, vbot), (left, v), (right, v), (right, vbot)
557
+
558
+ barareas = [volbar(i, v) for i, v in zip(x, vols)]
559
+ barcol = mcol.PolyCollection(
560
+ barareas,
561
+ facecolors=colors,
562
+ edgecolors=edgecolors,
563
+ antialiaseds=(0,),
564
+ linewidths=(0.5,),
565
+ **kwargs,
566
+ )
567
+
568
+ return barcol
569
+
570
+
571
+ def plot_volume(
572
+ ax,
573
+ x,
574
+ opens,
575
+ closes,
576
+ volumes,
577
+ colorup="k",
578
+ colordown="r",
579
+ edgeup=None,
580
+ edgedown=None,
581
+ edgeshading=-5,
582
+ edgeadjust=0.05,
583
+ width=1,
584
+ alpha=1.0,
585
+ **kwargs,
586
+ ):
587
+ """Plot volume chart on given axes.
588
+
589
+ Convenience function that creates a VolumePlotHandler and returns
590
+ the matplotlib collection for the volume chart.
591
+
592
+ Args:
593
+ ax: Matplotlib axes object to add collections to.
594
+ x: Array of x-axis coordinates (typically bar indices).
595
+ opens: Array of opening prices.
596
+ closes: Array of closing prices.
597
+ volumes: Array of volume values.
598
+ colorup: Color for up volume bars (close > open). Default is "k" (black).
599
+ colordown: Color for down volume bars (close < open). Default is "r" (red).
600
+ edgeup: Edge color for up bars. If None, derived from colorup with shading.
601
+ edgedown: Edge color for down bars. If None, derived from colordown with shading.
602
+ edgeshading: Shading factor for edge colors. Default is -5.
603
+ edgeadjust: Adjustment for edge width. Default is 0.05.
604
+ width: Width of volume bars. Default is 1.
605
+ alpha: Transparency level (0-1). Default is 1.0.
606
+ **kwargs: Additional keyword arguments passed to collection.
607
+
608
+ Returns:
609
+ Tuple containing the volume bar collection.
610
+ """
611
+ vhandler = VolumePlotHandler(
612
+ ax,
613
+ x,
614
+ opens,
615
+ closes,
616
+ volumes,
617
+ colorup,
618
+ colordown,
619
+ edgeup,
620
+ edgedown,
621
+ edgeshading,
622
+ edgeadjust,
623
+ width,
624
+ alpha,
625
+ **kwargs,
626
+ )
627
+
628
+ return (vhandler.barcol,)
629
+
630
+
631
+ class OHLCPlotHandler:
632
+ """Handler for creating and managing OHLC (Open-High-Low-Close) plot collections.
633
+
634
+ This class creates matplotlib line collections for rendering OHLC bar charts
635
+ with customizable colors for up and down bars.
636
+
637
+ Attributes:
638
+ legend_opens: Open prices for legend sample bars.
639
+ legend_highs: High prices for legend sample bars.
640
+ legend_lows: Low prices for legend sample bars.
641
+ legend_closes: Close prices for legend sample bars.
642
+ colorup: RGBA color for up bars (close > open).
643
+ colordown: RGBA color for down bars (close < open).
644
+ barcol: LineCollection containing the vertical high-low lines.
645
+ opencol: LineCollection containing the open tick marks.
646
+ closecol: LineCollection containing the close tick marks.
647
+ """
648
+
649
+ legend_opens = [0.50, 0.50, 0.50]
650
+ legend_highs = [1.00, 1.00, 1.00]
651
+ legend_lows = [0.00, 0.00, 0.00]
652
+ legend_closes = [0.80, 0.20, 0.90]
653
+
654
+ def __init__(
655
+ self,
656
+ ax,
657
+ x,
658
+ opens,
659
+ highs,
660
+ lows,
661
+ closes,
662
+ colorup="k",
663
+ colordown="r",
664
+ width=1,
665
+ tickwidth=0.5,
666
+ alpha=1.0,
667
+ label="_nolegend",
668
+ **kwargs,
669
+ ):
670
+ """Initialize the OHLC plot handler.
671
+
672
+ Args:
673
+ ax: Matplotlib axes object to add collections to.
674
+ x: Array of x-axis coordinates (typically bar indices).
675
+ opens: Array of opening prices.
676
+ highs: Array of high prices.
677
+ lows: Array of low prices.
678
+ closes: Array of closing prices.
679
+ colorup: Color for up bars (close > open). Default is "k" (black).
680
+ colordown: Color for down bars (close < open). Default is "r" (red).
681
+ width: Width of vertical high-low lines. Default is 1.
682
+ tickwidth: Width of open/close tick marks. Default is 0.5.
683
+ alpha: Transparency level (0-1). Default is 1.0.
684
+ label: Label for legend. Default is "_nolegend".
685
+ **kwargs: Additional keyword arguments passed to collections.
686
+
687
+ Raises:
688
+ ValueError: If color conversion fails.
689
+ """
690
+ # Manager up/down bar colors
691
+ r, g, b = mcolors.colorConverter.to_rgb(colorup)
692
+ self.colorup = r, g, b, alpha
693
+ r, g, b = mcolors.colorConverter.to_rgb(colordown)
694
+ self.colordown = r, g, b, alpha
695
+
696
+ bcol, ocol, ccol = self.barcollection(
697
+ x, opens, highs, lows, closes, width=width, tickwidth=tickwidth, label=label, **kwargs
698
+ )
699
+
700
+ self.barcol = bcol
701
+ self.opencol = ocol
702
+ self.closecol = ccol
703
+
704
+ # add collections to the axis and return them
705
+ ax.add_collection(self.barcol)
706
+ ax.add_collection(self.opencol)
707
+ ax.add_collection(self.closecol)
708
+
709
+ # Update the axis
710
+ ax.update_datalim(((0, min(lows)), (len(opens), max(highs))))
711
+ ax.autoscale_view()
712
+
713
+ # Add self as legend handler for this object
714
+ mlegend.Legend.update_default_handler_map({self.barcol: self})
715
+
716
+ def legend_artist(self, legend, orig_handle, fontsize, handlebox):
717
+ """Create a custom legend artist for OHLC plots.
718
+
719
+ Args:
720
+ legend: The legend object being created.
721
+ orig_handle: The original handle for which the artist is created.
722
+ fontsize: The font size for the legend.
723
+ handlebox: The handlebox container for positioning the legend artist.
724
+
725
+ Returns:
726
+ Tuple of (barcol, opencol, closecol): The line collections for the legend.
727
+ """
728
+ x0 = handlebox.xdescent
729
+ y0 = handlebox.ydescent
730
+ width = handlebox.width / len(self.legend_opens)
731
+ height = handlebox.height
732
+
733
+ # Generate the x-axis coordinates (handlebox based)
734
+ xs = [x0 + width * (i + 0.5) for i in range(len(self.legend_opens))]
735
+
736
+ barcol, opencol, closecol = self.barcollection(
737
+ xs,
738
+ self.legend_opens,
739
+ self.legend_highs,
740
+ self.legend_lows,
741
+ self.legend_closes,
742
+ width=1.5,
743
+ tickwidth=2,
744
+ scaling=height,
745
+ bot=y0,
746
+ )
747
+
748
+ barcol.set_transform(handlebox.get_transform())
749
+ handlebox.add_artist(barcol)
750
+ # opencol.set_transform(handlebox.get_transform())
751
+ handlebox.add_artist(opencol)
752
+ # closecol.set_transform(handlebox.get_transform())
753
+ handlebox.add_artist(closecol)
754
+
755
+ return barcol, opencol, closecol
756
+
757
+ def barcollection(
758
+ self,
759
+ xs,
760
+ opens,
761
+ highs,
762
+ lows,
763
+ closes,
764
+ width,
765
+ tickwidth,
766
+ label="_nolegend",
767
+ scaling=1.0,
768
+ bot=0,
769
+ **kwargs,
770
+ ):
771
+ """Create matplotlib collections for OHLC bars and tick marks.
772
+
773
+ Args:
774
+ xs: Array of x-axis coordinates.
775
+ opens: Array of opening prices.
776
+ highs: Array of high prices.
777
+ lows: Array of low prices.
778
+ closes: Array of closing prices.
779
+ width: Width of vertical high-low lines.
780
+ tickwidth: Width of open/close tick marks.
781
+ label: Label for legend. Default is "_nolegend".
782
+ scaling: Vertical scaling factor. Default is 1.0.
783
+ bot: Bottom offset for vertical positioning. Default is 0.
784
+ **kwargs: Additional keyword arguments passed to collections.
785
+
786
+ Returns:
787
+ Tuple of (barcol, opencol, closecol): LineCollection for bars,
788
+ open ticks, and close ticks.
789
+ """
790
+ # Prepack different zips of the series values
791
+ ihighlow = lambda: zip(xs, highs, lows) # NOQA: E731
792
+ iopen = lambda: zip(xs, opens) # NOQA: E731
793
+ iclose = lambda: zip(xs, closes) # NOQA: E731
794
+ openclose = lambda: zip(opens, closes) # NOQA: E731
795
+
796
+ colord = {True: self.colorup, False: self.colordown}
797
+ colors = [colord[open_ < close] for open_, close in openclose()]
798
+
799
+ # Extra variables for the collections
800
+ useaa = (0,)
801
+ lw = (width,)
802
+ tlw = (tickwidth,)
803
+
804
+ # Calculate the barranges
805
+ def barrange(i, high, low):
806
+ return (i, low * scaling + bot), (i, high * scaling + bot)
807
+
808
+ barranges = [barrange(i, high, low) for i, high, low in ihighlow()]
809
+
810
+ barcol = mcol.LineCollection(
811
+ barranges, colors=colors, linewidths=lw, antialiaseds=useaa, label=label, **kwargs
812
+ )
813
+
814
+ def tickopen(i, open_):
815
+ open_ = open_ * scaling + bot
816
+ return (i - tickwidth, open_), (i, open_)
817
+
818
+ openticks = [tickopen(i, open_) for i, open_ in iopen()]
819
+ opencol = mcol.LineCollection(
820
+ openticks,
821
+ colors=colors,
822
+ antialiaseds=useaa,
823
+ linewidths=tlw,
824
+ label="_nolegend",
825
+ **kwargs,
826
+ )
827
+
828
+ def tickclose(i, close):
829
+ close = close * scaling + bot
830
+ return (i, close), (i + tickwidth, close)
831
+
832
+ closeticks = [tickclose(i, close) for i, close in iclose()]
833
+ closecol = mcol.LineCollection(
834
+ closeticks,
835
+ colors=colors,
836
+ antialiaseds=useaa,
837
+ linewidths=tlw,
838
+ label="_nolegend",
839
+ **kwargs,
840
+ )
841
+
842
+ # return barcol, tickcol
843
+ return barcol, opencol, closecol
844
+
845
+
846
+ def plot_ohlc(
847
+ ax,
848
+ x,
849
+ opens,
850
+ highs,
851
+ lows,
852
+ closes,
853
+ colorup="k",
854
+ colordown="r",
855
+ width=1.5,
856
+ tickwidth=0.5,
857
+ alpha=1.0,
858
+ label="_nolegend",
859
+ **kwargs,
860
+ ):
861
+ """Plot OHLC (Open-High-Low-Close) chart on given axes.
862
+
863
+ Convenience function that creates an OHLCPlotHandler and returns
864
+ the matplotlib collections for the OHLC chart.
865
+
866
+ Args:
867
+ ax: Matplotlib axes object to add collections to.
868
+ x: Array of x-axis coordinates (typically bar indices).
869
+ opens: Array of opening prices.
870
+ highs: Array of high prices.
871
+ lows: Array of low prices.
872
+ closes: Array of closing prices.
873
+ colorup: Color for up bars (close > open). Default is "k" (black).
874
+ colordown: Color for down bars (close < open). Default is "r" (red).
875
+ width: Width of vertical high-low lines. Default is 1.5.
876
+ tickwidth: Width of open/close tick marks. Default is 0.5.
877
+ alpha: Transparency level (0-1). Default is 1.0.
878
+ label: Label for legend. Default is "_nolegend".
879
+ **kwargs: Additional keyword arguments passed to collections.
880
+
881
+ Returns:
882
+ Tuple of (barcol, opencol, closecol): LineCollection for bars,
883
+ open ticks, and close ticks.
884
+ """
885
+ handler = OHLCPlotHandler(
886
+ ax,
887
+ x,
888
+ opens,
889
+ highs,
890
+ lows,
891
+ closes,
892
+ colorup,
893
+ colordown,
894
+ width,
895
+ tickwidth,
896
+ alpha,
897
+ label,
898
+ **kwargs,
899
+ )
900
+
901
+ return handler.barcol, handler.opencol, handler.closecol
902
+
903
+
904
+ class LineOnClosePlotHandler:
905
+ """Handler for creating and managing line-on-close plot collections.
906
+
907
+ This class creates matplotlib line objects for rendering a simple line
908
+ chart of closing prices.
909
+
910
+ Attributes:
911
+ legend_closes: Sample close prices for legend rendering.
912
+ color: Color of the line.
913
+ alpha: Transparency level (0-1).
914
+ loc: Line2D object containing the close price line.
915
+ """
916
+
917
+ legend_closes = [0.00, 0.66, 0.33, 1.00]
918
+
919
+ def __init__(self, ax, x, closes, color="k", width=1, alpha=1.0, label="_nolegend", **kwargs):
920
+ """Initialize the line-on-close plot handler.
921
+
922
+ Args:
923
+ ax: Matplotlib axes object to add the line to.
924
+ x: Array of x-axis coordinates (typically bar indices).
925
+ closes: Array of closing prices.
926
+ color: Color of the line. Default is "k" (black).
927
+ width: Width of the line. Default is 1.
928
+ alpha: Transparency level (0-1). Default is 1.0.
929
+ label: Label for legend. Default is "_nolegend".
930
+ **kwargs: Additional keyword arguments passed to Line2D.
931
+ """
932
+ self.color = color
933
+ self.alpha = alpha
934
+
935
+ (self.loc,) = self.barcollection(x, closes, width=width, label=label, **kwargs)
936
+
937
+ # add collections to the axis and return them
938
+ ax.add_line(self.loc)
939
+
940
+ # Update the axis
941
+ ax.update_datalim(((x[0], min(closes)), (x[-1], max(closes))))
942
+ ax.autoscale_view()
943
+
944
+ # Add self as legend handler for this object
945
+ mlegend.Legend.update_default_handler_map({self.loc: self})
946
+
947
+ def legend_artist(self, legend, orig_handle, fontsize, handlebox):
948
+ """Create a custom legend artist for line-on-close plots.
949
+
950
+ Args:
951
+ legend: The legend object being created.
952
+ orig_handle: The original handle for which the artist is created.
953
+ fontsize: The font size for the legend.
954
+ handlebox: The handlebox container for positioning the legend artist.
955
+
956
+ Returns:
957
+ Tuple containing the line collection for the legend.
958
+ """
959
+ x0 = handlebox.xdescent
960
+ y0 = handlebox.ydescent
961
+ width = handlebox.width / len(self.legend_closes)
962
+ height = handlebox.height
963
+
964
+ # Generate the x-axis coordinates (handlebox based)
965
+ xs = [x0 + width * (i + 0.5) for i in range(len(self.legend_closes))]
966
+
967
+ (linecol,) = self.barcollection(xs, self.legend_closes, width=1.5, scaling=height, bot=y0)
968
+
969
+ linecol.set_transform(handlebox.get_transform())
970
+ handlebox.add_artist(linecol)
971
+
972
+ return (linecol,)
973
+
974
+ def barcollection(self, xs, closes, width, label="_nolegend", scaling=1.0, bot=0, **kwargs):
975
+ """Create matplotlib line object for close prices.
976
+
977
+ Args:
978
+ xs: Array of x-axis coordinates.
979
+ closes: Array of closing prices.
980
+ width: Width of the line.
981
+ label: Label for legend. Default is "_nolegend".
982
+ scaling: Vertical scaling factor. Default is 1.0.
983
+ bot: Bottom offset for vertical positioning. Default is 0.
984
+ **kwargs: Additional keyword arguments passed to Line2D.
985
+
986
+ Returns:
987
+ Tuple containing the Line2D object.
988
+ """
989
+ # Prepack different zips of the series values
990
+ scaled = [close * scaling + bot for close in closes]
991
+
992
+ loc = mlines.Line2D(
993
+ xs, scaled, color=self.color, lw=width, label=label, alpha=self.alpha, **kwargs
994
+ )
995
+
996
+ return (loc,)
997
+
998
+
999
+ def plot_lineonclose(ax, x, closes, color="k", width=1.5, alpha=1.0, label="_nolegend", **kwargs):
1000
+ """Plot line-on-close chart on given axes.
1001
+
1002
+ Convenience function that creates a LineOnClosePlotHandler and returns
1003
+ the matplotlib line object for the line chart.
1004
+
1005
+ Args:
1006
+ ax: Matplotlib axes object to add the line to.
1007
+ x: Array of x-axis coordinates (typically bar indices).
1008
+ closes: Array of closing prices.
1009
+ color: Color of the line. Default is "k" (black).
1010
+ width: Width of the line. Default is 1.5.
1011
+ alpha: Transparency level (0-1). Default is 1.0.
1012
+ label: Label for legend. Default is "_nolegend".
1013
+ **kwargs: Additional keyword arguments passed to Line2D.
1014
+
1015
+ Returns:
1016
+ Tuple containing the Line2D object.
1017
+ """
1018
+ handler = LineOnClosePlotHandler(
1019
+ ax, x, closes, color=color, width=width, alpha=alpha, label=label, **kwargs
1020
+ )
1021
+
1022
+ return (handler.loc,)