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,440 @@
1
+ #!/usr/bin/env python
2
+ """RSI Indicator Module - Relative Strength Index.
3
+
4
+ This module provides the RSI (Relative Strength Index) indicator
5
+ developed by J. Welles Wilder, Jr.
6
+
7
+ Classes:
8
+ RSI: RSI indicator.
9
+ UpDay/DownDay: Helper classes for RSI calculation.
10
+
11
+ Example:
12
+ class MyStrategy(bt.Strategy):
13
+ def __init__(self):
14
+ self.rsi = bt.indicators.RSI(self.data.close, period=14)
15
+
16
+ def next(self):
17
+ # RSI above 70 indicates overbought
18
+ if self.rsi.rsi[0] > 70:
19
+ self.sell()
20
+ # RSI below 30 indicates oversold
21
+ elif self.rsi.rsi[0] < 30:
22
+ self.buy()
23
+ """
24
+
25
+ import math
26
+
27
+ from . import Indicator, MovAv
28
+
29
+
30
+ # Calculate RSI indicator
31
+ class UpDay(Indicator):
32
+ """
33
+ Defined by J. Welles Wilder, Jr. in 1978 in his book *"New Concepts in
34
+ Technical Trading Systems"* for the RSI
35
+
36
+ Records days which have been "up", i.e.: the close price has been
37
+ higher than the day before.
38
+
39
+ Formula:
40
+ - upday = max (close - close_prev, 0)
41
+
42
+ See:
43
+ - http://en.wikipedia.org/wiki/Relative_strength_index
44
+ """
45
+
46
+ lines = ("upday",)
47
+ params = (("period", 1),)
48
+
49
+ def __init__(self):
50
+ """Initialize the UpDay indicator.
51
+
52
+ Sets minimum period for up day calculation.
53
+ """
54
+ super().__init__()
55
+ self.addminperiod(self.p.period + 1)
56
+
57
+ def next(self):
58
+ """Calculate up day value for the current bar.
59
+
60
+ Returns max(close - close_period_ago, 0).
61
+ """
62
+ diff = self.data[0] - self.data[-self.p.period]
63
+ self.lines.upday[0] = max(diff, 0.0)
64
+
65
+ def once(self, start, end):
66
+ """Calculate up day values in runonce mode.
67
+
68
+ Returns max(price_change, 0) for each bar.
69
+ """
70
+ darray = self.data.array
71
+ larray = self.lines.upday.array
72
+ period = self.p.period
73
+
74
+ while len(larray) < end:
75
+ larray.append(0.0)
76
+
77
+ for i in range(min(period, end, len(larray))):
78
+ larray[i] = 0.0
79
+
80
+ for i in range(period, min(end, len(darray))):
81
+ diff = darray[i] - darray[i - period]
82
+ larray[i] = max(diff, 0.0)
83
+
84
+
85
+ class DownDay(Indicator):
86
+ """
87
+ Defined by J. Welles Wilder, Jr. in 1978 in his book *"New Concepts in
88
+ Technical Trading Systems"* for the RSI
89
+
90
+ Records days which have been "down", i.e.: the close price has been
91
+ lower than the day before.
92
+
93
+ Formula:
94
+ - downday = max(close_prev - close, 0)
95
+
96
+ See:
97
+ - http://en.wikipedia.org/wiki/Relative_strength_index
98
+ """
99
+
100
+ lines = ("downday",)
101
+ params = (("period", 1),)
102
+
103
+ def __init__(self):
104
+ """Initialize the DownDay indicator.
105
+
106
+ Sets minimum period for down day calculation.
107
+ """
108
+ super().__init__()
109
+ self.addminperiod(self.p.period + 1)
110
+
111
+ def next(self):
112
+ """Calculate down day value for the current bar.
113
+
114
+ Returns max(close_period_ago - close, 0).
115
+ """
116
+ diff = self.data[-self.p.period] - self.data[0]
117
+ self.lines.downday[0] = max(diff, 0.0)
118
+
119
+ def once(self, start, end):
120
+ """Calculate down day values in runonce mode.
121
+
122
+ Returns max(-price_change, 0) for each bar.
123
+ """
124
+ darray = self.data.array
125
+ larray = self.lines.downday.array
126
+ period = self.p.period
127
+
128
+ while len(larray) < end:
129
+ larray.append(0.0)
130
+
131
+ for i in range(min(period, end, len(larray))):
132
+ larray[i] = 0.0
133
+
134
+ for i in range(period, min(end, len(darray))):
135
+ diff = darray[i - period] - darray[i]
136
+ larray[i] = max(diff, 0.0)
137
+
138
+
139
+ class UpDayBool(Indicator):
140
+ """
141
+ Defined by J. Welles Wilder, Jr. in 1978 in his book *"New Concepts in
142
+ Technical Trading Systems"* for the RSI
143
+
144
+ Records days which have been "up", i.e.: the close price has been
145
+ higher than the day before.
146
+
147
+ Note:
148
+ - This version returns a bool rather than the difference
149
+
150
+ Formula:
151
+ - upday = close > close_prev
152
+
153
+ See:
154
+ - http://en.wikipedia.org/wiki/Relative_strength_index
155
+ """
156
+
157
+ lines = ("upday",)
158
+ params = (("period", 1),)
159
+
160
+ def __init__(self):
161
+ """Initialize the UpDay Bool indicator.
162
+
163
+ Sets minimum period for boolean up day calculation.
164
+ """
165
+ super().__init__()
166
+ self.addminperiod(self.p.period + 1)
167
+
168
+ def next(self):
169
+ """Check if current bar is an up day.
170
+
171
+ Returns 1.0 if close > close_period_ago, 0.0 otherwise.
172
+ """
173
+ self.lines.upday[0] = 1.0 if self.data[0] > self.data[-self.p.period] else 0.0
174
+
175
+ def once(self, start, end):
176
+ """Check for up days in runonce mode.
177
+
178
+ Returns 1.0 where price increased, 0.0 otherwise.
179
+ """
180
+ darray = self.data.array
181
+ larray = self.lines.upday.array
182
+ period = self.p.period
183
+
184
+ while len(larray) < end:
185
+ larray.append(0.0)
186
+
187
+ for i in range(min(period, end, len(larray))):
188
+ larray[i] = 0.0
189
+
190
+ for i in range(period, min(end, len(darray))):
191
+ larray[i] = 1.0 if darray[i] > darray[i - period] else 0.0
192
+
193
+
194
+ class DownDayBool(Indicator):
195
+ """
196
+ Defined by J. Welles Wilder, Jr. in 1978 in his book *"New Concepts in
197
+ Technical Trading Systems"* for the RSI
198
+
199
+ Records days which have been "down", i.e.: the close price has been
200
+ lower than the day before.
201
+
202
+ Note:
203
+ - This version returns a bool rather than the difference
204
+
205
+ Formula:
206
+ - downday = close_prev > close
207
+
208
+ See:
209
+ - http://en.wikipedia.org/wiki/Relative_strength_index
210
+ """
211
+
212
+ lines = ("downday",)
213
+ params = (("period", 1),)
214
+
215
+ def __init__(self):
216
+ """Initialize the DownDay Bool indicator.
217
+
218
+ Sets minimum period for boolean down day calculation.
219
+ """
220
+ super().__init__()
221
+ self.addminperiod(self.p.period + 1)
222
+
223
+ def next(self):
224
+ """Check if current bar is a down day.
225
+
226
+ Returns 1.0 if close_period_ago > close, 0.0 otherwise.
227
+ """
228
+ self.lines.downday[0] = 1.0 if self.data[-self.p.period] > self.data[0] else 0.0
229
+
230
+ def once(self, start, end):
231
+ """Check for down days in runonce mode.
232
+
233
+ Returns 1.0 where price decreased, 0.0 otherwise.
234
+ """
235
+ darray = self.data.array
236
+ larray = self.lines.downday.array
237
+ period = self.p.period
238
+
239
+ while len(larray) < end:
240
+ larray.append(0.0)
241
+
242
+ for i in range(min(period, end, len(larray))):
243
+ larray[i] = 0.0
244
+
245
+ for i in range(period, min(end, len(darray))):
246
+ larray[i] = 1.0 if darray[i - period] > darray[i] else 0.0
247
+
248
+
249
+ class RelativeStrengthIndex(Indicator):
250
+ """Defined by J. Welles Wilder, Jr. in 1978 in his book *"New Concepts in
251
+ Technical Trading Systems"*.
252
+
253
+ It measures momentum by calculating the ration of higher closes and
254
+ lower closes after having been smoothed by an average, normalizing
255
+ the result between 0 and 100
256
+
257
+ Formula:
258
+ - up = upday(data)
259
+ - down = downday(data)
260
+ - maup = movingaverage(up, period)
261
+ - madown = movingaverage(down, period)
262
+ - rs = maup / madown
263
+ - rsi = 100 - 100 / (1 + rs)
264
+
265
+ The moving average used is the one originally defined by Wilder,
266
+ the SmoothedMovingAverage
267
+
268
+ See:
269
+ - http://en.wikipedia.org/wiki/Relative_strength_index
270
+
271
+ Notes:
272
+ - ``safediv`` (default: False) If this parameter is True, the division
273
+ rs = maup / madown will be checked for the special cases in which a
274
+ ``0 / 0`` or ``x / 0`` division will happen
275
+
276
+ - ``safehigh`` (default: 100.0) will be used as RSI value for the
277
+ ``x / 0`` case
278
+
279
+ - ``safelow`` (default: 50.0) will be used as RSI value for the
280
+ ``0 / 0`` case
281
+ """
282
+
283
+ alias = (
284
+ "RSI",
285
+ "RSI_SMMA",
286
+ "RSI_Wilder",
287
+ )
288
+
289
+ lines = ("rsi",)
290
+ params = (
291
+ ("period", 14),
292
+ ("movav", MovAv.Smoothed),
293
+ ("upperband", 70.0),
294
+ ("lowerband", 30.0),
295
+ ("safediv", False),
296
+ ("safehigh", 100.0),
297
+ ("safelow", 50.0),
298
+ ("lookback", 1),
299
+ )
300
+
301
+ def _plotlabel(self):
302
+ plabels = [self.p.period]
303
+ plabels += [self.p.movav] * self.p.notdefault("movav")
304
+ plabels += [self.p.lookback] * self.p.notdefault("lookback")
305
+ return plabels
306
+
307
+ def _plotinit(self):
308
+ self.plotinfo.plotyhlines = [self.p.upperband, self.p.lowerband]
309
+
310
+ def __init__(self):
311
+ """Initialize the RSI indicator.
312
+
313
+ Creates up/down day indicators and their moving averages.
314
+ """
315
+ super().__init__()
316
+ self.upday = UpDay(self.data, period=self.p.lookback)
317
+ self.downday = DownDay(self.data, period=self.p.lookback)
318
+ self.maup = self.p.movav(self.upday, period=self.p.period)
319
+ self.madown = self.p.movav(self.downday, period=self.p.period)
320
+
321
+ def _rscalc(self, rsi):
322
+ """Calculate relative strength from RSI value."""
323
+ try:
324
+ rs = (-100.0 / (rsi - 100.0)) - 1.0
325
+ except ZeroDivisionError:
326
+ return float("inf")
327
+ return rs
328
+
329
+ def _calc_rsi(self, maup_val, madown_val):
330
+ """Calculate RSI from maup and madown values.
331
+
332
+ Args:
333
+ maup_val: Moving average of up days.
334
+ madown_val: Moving average of down days.
335
+
336
+ Returns:
337
+ RSI value between 0 and 100.
338
+ """
339
+ if self.p.safediv:
340
+ if madown_val == 0.0:
341
+ if maup_val == 0.0:
342
+ return self.p.safelow # 0/0 case
343
+ return self.p.safehigh # x/0 case
344
+
345
+ if madown_val == 0.0:
346
+ return 100.0 # Avoid division by zero
347
+
348
+ rs = maup_val / madown_val
349
+ return 100.0 - 100.0 / (1.0 + rs)
350
+
351
+ def next(self):
352
+ """Calculate RSI for the current bar.
353
+
354
+ RSI = 100 - 100 / (1 + maup/madown)
355
+ """
356
+ self.lines.rsi[0] = self._calc_rsi(self.maup[0], self.madown[0])
357
+
358
+ def once(self, start, end):
359
+ """Calculate RSI in runonce mode.
360
+
361
+ Computes RSI values across all bars with safe division handling.
362
+ """
363
+ for child in (self.upday, self.downday, self.maup, self.madown):
364
+ if hasattr(child, "once"):
365
+ child.once(0, end)
366
+
367
+ maup_array = self.maup.lines[0].array
368
+ madown_array = self.madown.lines[0].array
369
+ larray = self.lines.rsi.array
370
+ safediv = self.p.safediv
371
+ safehigh = self.p.safehigh
372
+ safelow = self.p.safelow
373
+
374
+ while len(larray) < end:
375
+ larray.append(float("nan"))
376
+
377
+ for i in range(start, min(end, len(maup_array), len(madown_array))):
378
+ maup_val = maup_array[i] if i < len(maup_array) else 0.0
379
+ madown_val = madown_array[i] if i < len(madown_array) else 0.0
380
+
381
+ if (
382
+ isinstance(maup_val, float)
383
+ and math.isnan(maup_val)
384
+ or isinstance(madown_val, float)
385
+ and math.isnan(madown_val)
386
+ ):
387
+ larray[i] = float("nan")
388
+ else:
389
+ if safediv:
390
+ if madown_val == 0.0:
391
+ if maup_val == 0.0:
392
+ larray[i] = safelow
393
+ else:
394
+ larray[i] = safehigh
395
+ continue
396
+
397
+ if madown_val == 0.0:
398
+ larray[i] = 100.0
399
+ else:
400
+ rs = maup_val / madown_val
401
+ larray[i] = 100.0 - 100.0 / (1.0 + rs)
402
+
403
+
404
+ RSI = RelativeStrengthIndex
405
+
406
+
407
+ class RSI_Safe(RSI):
408
+ """
409
+ Subclass of RSI which changes parameers ``safediv`` to ``True`` as the
410
+ default value
411
+
412
+ See:
413
+ - http://en.wikipedia.org/wiki/Relative_strength_index
414
+ """
415
+
416
+ params = (("safediv", True),)
417
+
418
+
419
+ class RSI_SMA(RSI):
420
+ """
421
+ Uses a SimpleMovingAverage as described in Wikipedia and other soures
422
+
423
+ See:
424
+ - http://en.wikipedia.org/wiki/Relative_strength_index
425
+ """
426
+
427
+ alias = ("RSI_Cutler",)
428
+
429
+ params = (("movav", MovAv.Simple),)
430
+
431
+
432
+ class RSI_EMA(RSI):
433
+ """
434
+ Uses an ExponentialMovingAverage as described in Wikipedia
435
+
436
+ See:
437
+ - http://en.wikipedia.org/wiki/Relative_strength_index
438
+ """
439
+
440
+ params = (("movav", MovAv.Exponential),)
@@ -0,0 +1,141 @@
1
+ #!/usr/bin/env python
2
+ """SMA Indicator Module - Simple Moving Average.
3
+
4
+ This module provides the SMA (Simple Moving Average) indicator for
5
+ calculating the non-weighted average of the last n periods.
6
+
7
+ Classes:
8
+ MovingAverageSimple: SMA indicator (alias: SMA).
9
+
10
+ Example:
11
+ class MyStrategy(bt.Strategy):
12
+ def __init__(self):
13
+ self.sma = bt.indicators.SMA(self.data.close, period=20)
14
+
15
+ def next(self):
16
+ if self.data.close[0] > self.sma[0]:
17
+ self.buy()
18
+ elif self.data.close[0] < self.sma[0]:
19
+ self.sell()
20
+ """
21
+
22
+ import math
23
+
24
+ from ..utils.log_message import get_logger
25
+ from .mabase import MovingAverageBase
26
+
27
+ logger = get_logger(__name__)
28
+
29
+
30
+ # Moving average indicator
31
+ class MovingAverageSimple(MovingAverageBase):
32
+ """
33
+ Non-weighted average of the last n periods
34
+
35
+ Formula:
36
+ - movav = Sum(data, period) / period
37
+
38
+ See also:
39
+ - http://en.wikipedia.org/wiki/Moving_average#Simple_moving_average
40
+ """
41
+
42
+ alias = (
43
+ "SMA",
44
+ "SimpleMovingAverage",
45
+ )
46
+ lines = ("sma",)
47
+
48
+ def __init__(self):
49
+ """Initialize the SMA indicator."""
50
+ # Before super to ensure mixins (right-hand side in subclassing)
51
+ # can see the assignment operation and operate on the line
52
+ super().__init__()
53
+ self._period = self.p.period
54
+ self._next_offsets = tuple(range(1 - self._period, 1))
55
+ data = getattr(self, "data", None)
56
+ self._data_getitem = data.__getitem__ if data is not None else None
57
+ self._data_get = data.get if data is not None else None
58
+ self._sma_line = self.lines.sma
59
+ self._fsum = math.fsum
60
+
61
+ def nextstart(self):
62
+ """Initialize on first call after minperiod is met."""
63
+ # Delegate to next() — at this point we have exactly enough data
64
+ self.next()
65
+
66
+ def next(self):
67
+ """Calculate SMA for the current bar.
68
+
69
+ Recalculates from scratch each bar using sum of the last 'period'
70
+ values to avoid floating-point drift from incremental updates.
71
+ """
72
+ try:
73
+ data_get = self._data_get
74
+ if data_get is None:
75
+ data = self.data
76
+ data_get = data.get
77
+ self._data_get = data_get
78
+ self._data_getitem = data.__getitem__
79
+
80
+ prices = data_get(size=self._period)
81
+ if len(prices) != self._period:
82
+ data_getitem = self._data_getitem
83
+ if data_getitem is None:
84
+ data_getitem = self.data.__getitem__
85
+ self._data_getitem = data_getitem
86
+ prices = [float(data_getitem(i)) for i in self._next_offsets]
87
+ self._sma_line[0] = self._fsum(prices) / self._period
88
+ except (AttributeError, ValueError, TypeError, IndexError):
89
+ logger.debug("SMA next() failed", exc_info=True)
90
+ self._sma_line[0] = float("nan")
91
+
92
+ def once(self, start, end):
93
+ """Batch calculation for runonce mode."""
94
+ try:
95
+ # If data source is a LinesOperation, ensure its once() is called first
96
+ if hasattr(self.data, "once") and hasattr(self.data, "operation"):
97
+ try:
98
+ self.data.once(start, end)
99
+ except Exception as e:
100
+ logger.debug("data.once() failed in SMA: %s", e)
101
+
102
+ dst = self.lines[0].array
103
+ src = self.data.array
104
+ period = self.p.period
105
+ actual_end = min(end, len(src))
106
+
107
+ # Ensure destination array is large enough, pre-fill with NaN
108
+ while len(dst) < end:
109
+ dst.append(float("nan"))
110
+
111
+ # Pre-fill warmup period with NaN
112
+ for i in range(min(period - 1, len(src))):
113
+ dst[i] = float("nan")
114
+
115
+ calc_start = max(period - 1, start)
116
+ fsum = math.fsum # Cache function reference
117
+ nan_val = float("nan")
118
+
119
+ for i in range(calc_start, actual_end):
120
+ start_idx = i - period + 1
121
+ end_idx = i + 1
122
+ if end_idx <= len(src):
123
+ window = src[start_idx:end_idx]
124
+ # NaN check: only NaN != NaN (faster than isinstance + isnan)
125
+ has_nan = False
126
+ for v in window:
127
+ if v != v:
128
+ has_nan = True
129
+ break
130
+ if has_nan:
131
+ dst[i] = nan_val
132
+ else:
133
+ dst[i] = fsum(window) / period
134
+ else:
135
+ dst[i] = nan_val
136
+ except Exception:
137
+ logger.debug("SMA once() failed, falling back to once_via_next", exc_info=True)
138
+ super().once_via_next(start, end)
139
+
140
+
141
+ SMA = MovingAverageSimple
@@ -0,0 +1,116 @@
1
+ #!/usr/bin/env python
2
+ """SMMA Indicator Module - Smoothed Moving Average.
3
+
4
+ This module provides the SMMA (Smoothed Moving Average) indicator used
5
+ by J. Welles Wilder in his 1978 book.
6
+
7
+ Classes:
8
+ SmoothedMovingAverage: SMMA indicator (aliases: SMMA, WilderMA,
9
+ MovingAverageSmoothed, MovingAverageWilder, ModifiedMovingAverage).
10
+
11
+ Example:
12
+ class MyStrategy(bt.Strategy):
13
+ def __init__(self):
14
+ self.smma = bt.indicators.SMMA(self.data.close, period=14)
15
+
16
+ def next(self):
17
+ if self.data.close[0] > self.smma[0]:
18
+ self.buy()
19
+ """
20
+
21
+ from . import MovingAverageBase
22
+
23
+
24
+ class SmoothedMovingAverage(MovingAverageBase):
25
+ """
26
+ Smoothing Moving Average used by Wilder in his 1978 book `New Concepts in
27
+ Technical Trading`
28
+
29
+ Defined in his book originally as:
30
+
31
+ - new_value = (old_value * (period - 1) + new_data) / period
32
+
33
+ It Can be expressed as a SmoothingMovingAverage with the following factors:
34
+
35
+ - self.smfactor -> 1.0 / period
36
+ - self.smfactor1 -> `1.0 - self.smfactor`
37
+
38
+ Formula:
39
+ - movav = prev * (1.0 - smoothfactor) + newdata * smoothfactor
40
+
41
+ See also:
42
+ - http://en.wikipedia.org/wiki/Moving_average#Modified_moving_average
43
+ """
44
+
45
+ alias = (
46
+ "SMMA",
47
+ "WilderMA",
48
+ "MovingAverageSmoothed",
49
+ "MovingAverageWilder",
50
+ "ModifiedMovingAverage",
51
+ )
52
+ lines = ("smma",)
53
+
54
+ def __init__(self):
55
+ """Initialize the SMMA indicator.
56
+
57
+ Calculates alpha and alpha1 smoothing factors for the
58
+ smoothed moving average calculation.
59
+ """
60
+ super().__init__()
61
+ self.alpha = 1.0 / self.p.period
62
+ self.alpha1 = 1.0 - self.alpha
63
+
64
+ def nextstart(self):
65
+ """Seed SMMA calculation with SMA on first valid bar.
66
+
67
+ Initializes with simple moving average of the first period values.
68
+ """
69
+ # Seed value: SMA of first period values
70
+ period = self.p.period
71
+ data_sum = 0.0
72
+ for i in range(period):
73
+ data_sum += self.data[-i]
74
+ self.lines[0][0] = data_sum / period
75
+
76
+ def next(self):
77
+ """Calculate SMMA for the current bar.
78
+
79
+ Formula: SMMA = prev_SMMMA * alpha1 + current_price * alpha
80
+ where alpha = 1/period and alpha1 = 1 - alpha.
81
+ """
82
+ # SMMA formula: prev * alpha1 + current * alpha
83
+ self.lines[0][0] = self.lines[0][-1] * self.alpha1 + self.data[0] * self.alpha
84
+
85
+ def once(self, start, end):
86
+ """Calculate SMMA in runonce mode"""
87
+ darray = self.data.array
88
+ larray = self.lines[0].array
89
+ alpha = self.alpha
90
+ alpha1 = self.alpha1
91
+ period = self.p.period
92
+
93
+ # Ensure output array is properly sized
94
+ while len(larray) < end:
95
+ larray.append(float("nan"))
96
+
97
+ limit = min(end, len(darray))
98
+ for i in range(limit):
99
+ larray[i] = float("nan")
100
+
101
+ # Seed at self._minperiod - 1 to match nextstart() behavior.
102
+ # nextstart() sums self.data[-i] for i in range(period) at the first
103
+ # valid bar, which corresponds to darray[seed_idx - period + 1 : seed_idx + 1].
104
+ seed_idx = self._minperiod - 1
105
+ if seed_idx >= limit or seed_idx < period - 1:
106
+ return
107
+
108
+ seed_start = seed_idx - period + 1
109
+ prev = sum(float(darray[j]) for j in range(seed_start, seed_idx + 1)) / period
110
+ larray[seed_idx] = prev
111
+
112
+ # SMMA is recursive - must calculate ALL values from period onwards
113
+ for i in range(seed_idx + 1, limit):
114
+ current_val = float(darray[i])
115
+ prev = prev * alpha1 + current_val * alpha
116
+ larray[i] = prev