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,123 @@
1
+ #!/usr/bin/env python
2
+ """Price transform and simple signal indicators.
3
+
4
+ This module hosts small price-derived indicators migrated from functional
5
+ strategy tests. They are intentionally lightweight and depend only on the
6
+ standard Backtrader line API so they can be reused as ``bt.indicators.Xxx``.
7
+ """
8
+
9
+ from . import Indicator
10
+ from .sma import SMA
11
+
12
+ __all__ = [
13
+ "HighLowAverage",
14
+ "MedianPrice",
15
+ "PercentReturnsPeriod",
16
+ "SMACloseSignal",
17
+ "TypicalPrice",
18
+ "WeightedPrice",
19
+ ]
20
+
21
+
22
+ class WeightedPrice(Indicator):
23
+ """Weighted price ``(high + low + 2 * close) / 4``.
24
+
25
+ The indicator exposes both ``value`` and ``weighted`` lines because the
26
+ migrated functional tests used both names for the same formula.
27
+ """
28
+
29
+ lines = ("value", "weighted")
30
+
31
+ def __init__(self):
32
+ """Wire the weighted price series into both ``value`` and ``weighted`` lines."""
33
+ weighted = (self.data.high + self.data.low + self.data.close * 2.0) / 4.0
34
+ self.lines.value = weighted
35
+ self.lines.weighted = weighted
36
+
37
+
38
+ class MedianPrice(Indicator):
39
+ """Median price ``(high + low) / 2``."""
40
+
41
+ lines = ("value", "median")
42
+
43
+ def __init__(self):
44
+ """Wire the median-price series into both ``value`` and ``median`` lines."""
45
+ median = (self.data.high + self.data.low) / 2.0
46
+ self.lines.value = median
47
+ self.lines.median = median
48
+
49
+
50
+ class TypicalPrice(Indicator):
51
+ """Typical price ``(high + low + close) / 3``."""
52
+
53
+ lines = ("typical", "value")
54
+
55
+ def __init__(self):
56
+ """Wire the typical-price series into both ``typical`` and ``value`` lines."""
57
+ typical = (self.data.high + self.data.low + self.data.close) / 3.0
58
+ self.lines.typical = typical
59
+ self.lines.value = typical
60
+
61
+
62
+ class HighLowAverage(Indicator):
63
+ """Rolling average of the high-low range."""
64
+
65
+ lines = ("avg",)
66
+ params = (("period", 50),)
67
+
68
+ def __init__(self):
69
+ """Reserve the rolling window used for the high-low range average."""
70
+ self.addminperiod(self.p.period)
71
+
72
+ def next(self):
73
+ """Write the mean high-low range over the configured window to ``avg``.
74
+
75
+ Sums ``high - low`` for each of the last ``period`` bars
76
+ (current inclusive) and divides by ``period``. The output
77
+ line is updated in place; no value is returned.
78
+ """
79
+ total = 0.0
80
+ for i in range(self.p.period):
81
+ total += float(self.data.high[-i] - self.data.low[-i])
82
+ self.lines.avg[0] = total / self.p.period
83
+
84
+
85
+ class PercentReturnsPeriod(Indicator):
86
+ """Percentage return over ``period`` bars using the close line."""
87
+
88
+ lines = ("returns",)
89
+ params = (("period", 40),)
90
+
91
+ def __init__(self):
92
+ """Reserve the rolling window used for the percentage return."""
93
+ self.addminperiod(self.p.period)
94
+
95
+ def next(self):
96
+ """Write ``(close - close[-period]) / close[-period]`` to ``returns``.
97
+
98
+ Uses the close at ``-period`` as the baseline so the value
99
+ is the simple percentage change over the configured window.
100
+ When the baseline is zero the value is forced to ``0`` to
101
+ avoid a division-by-zero error.
102
+ """
103
+ previous = self.data.close[-self.p.period]
104
+ if previous != 0:
105
+ self.lines.returns[0] = (self.data.close[0] - previous) / previous
106
+ else:
107
+ self.lines.returns[0] = 0
108
+
109
+
110
+ class SMACloseSignal(Indicator):
111
+ """Signal line equal to current price minus its SMA."""
112
+
113
+ lines = ("signal",)
114
+ params = (("period", 30),)
115
+
116
+ def __init__(self):
117
+ """Compute ``data - SMA(data, period)`` and bind it to the ``signal`` line.
118
+
119
+ The line goes positive when the close is above its SMA and
120
+ negative when it is below, making it a simple momentum
121
+ proxy.
122
+ """
123
+ self.lines.signal = self.data - SMA(self.data, period=self.p.period)
@@ -0,0 +1,262 @@
1
+ #!/usr/bin/env python
2
+ """Price Oscillator Module - Price oscillators.
3
+
4
+ This module provides Price Oscillator indicators that measure the
5
+ difference between two moving averages.
6
+
7
+ Classes:
8
+ _PriceOscBase: Base class for price oscillators.
9
+ PriceOscillator: Price difference (aliases: PriceOsc, APO, AbsPriceOsc).
10
+ PercentagePriceOscillator: Percentage price oscillator (aliases: PPO, PercPriceOsc).
11
+ PercentagePriceOscillatorShort: PPO with short denominator (aliases: PPOShort).
12
+
13
+ Example:
14
+ class MyStrategy(bt.Strategy):
15
+ def __init__(self):
16
+ self.ppo = bt.indicators.PPO(self.data, period1=12, period2=26)
17
+
18
+ def next(self):
19
+ if self.ppo.ppo[0] > self.ppo.signal[0]:
20
+ self.buy()
21
+ elif self.ppo.ppo[0] < self.ppo.signal[0]:
22
+ self.sell()
23
+ """
24
+
25
+ import math
26
+
27
+ from . import Indicator, MovAv
28
+
29
+
30
+ class _PriceOscBase(Indicator):
31
+ params = (
32
+ ("period1", 12),
33
+ ("period2", 26),
34
+ ("_movav", MovAv.Exponential),
35
+ )
36
+
37
+ plotinfo = {"plothlines": [0.0]}
38
+
39
+ def __init__(self):
40
+ """Initialize the price oscillator base class.
41
+
42
+ Creates two moving averages with configured periods.
43
+ """
44
+ super().__init__()
45
+ self.ma1 = self.p._movav(self.data, period=self.p.period1)
46
+ self.ma2 = self.p._movav(self.data, period=self.p.period2)
47
+
48
+ def next(self):
49
+ """Calculate oscillator value: ma1 - ma2."""
50
+ self.lines[0][0] = self.ma1[0] - self.ma2[0]
51
+
52
+ def once(self, start, end):
53
+ """Calculate oscillator in runonce mode."""
54
+ ma1_array = self.ma1.lines[0].array
55
+ ma2_array = self.ma2.lines[0].array
56
+ larray = self.lines[0].array
57
+
58
+ while len(larray) < end:
59
+ larray.append(float("nan"))
60
+
61
+ for i in range(start, min(end, len(ma1_array), len(ma2_array))):
62
+ ma1_val = ma1_array[i] if i < len(ma1_array) else 0.0
63
+ ma2_val = ma2_array[i] if i < len(ma2_array) else 0.0
64
+
65
+ if (
66
+ isinstance(ma1_val, float)
67
+ and math.isnan(ma1_val)
68
+ or isinstance(ma2_val, float)
69
+ and math.isnan(ma2_val)
70
+ ):
71
+ larray[i] = float("nan")
72
+ else:
73
+ larray[i] = ma1_val - ma2_val
74
+
75
+
76
+ # Moving average difference
77
+ class PriceOscillator(_PriceOscBase):
78
+ """
79
+ Shows the difference between a short and long exponential moving
80
+ averages expressed in points.
81
+
82
+ Formula:
83
+ - po = ema(short) - ema(long)
84
+
85
+ See:
86
+ - http://www.metastock.com/Customer/Resources/TAAZ/?c=3&p=94
87
+ """
88
+
89
+ alias = (
90
+ "PriceOsc",
91
+ "AbsolutePriceOscillator",
92
+ "APO",
93
+ "AbsPriceOsc",
94
+ )
95
+ lines = ("po",)
96
+
97
+
98
+ # Similar to MACD indicator, expressed in percentage
99
+ class PercentagePriceOscillator(_PriceOscBase):
100
+ """
101
+ Shows the difference between a short and long exponential moving
102
+ averages expressed in percentage. The MACD does the same but expressed in
103
+ absolute points.
104
+
105
+ Expressing the difference in percentage allows to compare the indicator at
106
+ different points in time when the underlying value has significatnly
107
+ different values.
108
+
109
+ Formula:
110
+ - po = 100 * (ema(short) - ema(long)) / ema(long)
111
+
112
+ See:
113
+ - http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:price_oscillators_ppo
114
+ """
115
+
116
+ _long = True
117
+
118
+ alias = (
119
+ "PPO",
120
+ "PercPriceOsc",
121
+ )
122
+
123
+ lines = ("ppo", "signal", "histo")
124
+ params = (("period_signal", 9),)
125
+
126
+ plotlines = {"histo": {"_method": "bar", "alpha": 0.50, "width": 1.0}}
127
+
128
+ def __init__(self):
129
+ """Initialize the PPO indicator.
130
+
131
+ Sets up signal line EMA parameters.
132
+ """
133
+ super().__init__()
134
+ self.signal_alpha = 2.0 / (1.0 + self.p.period_signal)
135
+ self.signal_alpha1 = 1.0 - self.signal_alpha
136
+
137
+ def next(self):
138
+ """Calculate PPO, signal, and histogram for current bar.
139
+
140
+ PPO = 100 * (ma1 - ma2) / ma2
141
+ Signal = EMA(PPO)
142
+ Histogram = PPO - Signal
143
+ """
144
+ # Calculate base PO
145
+ po_val = self.ma1[0] - self.ma2[0]
146
+
147
+ # Calculate PPO
148
+ den = self.ma2[0] if self._long else self.ma1[0]
149
+ if den != 0:
150
+ ppo_val = 100.0 * po_val / den
151
+ else:
152
+ ppo_val = 0.0
153
+ self.lines.ppo[0] = ppo_val
154
+
155
+ # Calculate signal (EMA of PPO)
156
+ self.lines.signal[0] = (
157
+ self.lines.signal[-1] * self.signal_alpha1 + ppo_val * self.signal_alpha
158
+ )
159
+
160
+ # Calculate histogram
161
+ self.lines.histo[0] = self.lines.ppo[0] - self.lines.signal[0]
162
+
163
+ def nextstart(self):
164
+ """Seed PPO calculation on first valid bar.
165
+
166
+ Initializes signal line with first PPO value.
167
+ """
168
+ # Calculate base PO
169
+ po_val = self.ma1[0] - self.ma2[0]
170
+
171
+ # Calculate PPO
172
+ den = self.ma2[0] if self._long else self.ma1[0]
173
+ if den != 0:
174
+ ppo_val = 100.0 * po_val / den
175
+ else:
176
+ ppo_val = 0.0
177
+ self.lines.ppo[0] = ppo_val
178
+
179
+ # Seed signal with PPO
180
+ self.lines.signal[0] = ppo_val
181
+
182
+ # Calculate histogram
183
+ self.lines.histo[0] = 0.0
184
+
185
+ def once(self, start, end):
186
+ """Calculate PPO in runonce mode."""
187
+ ma1_array = self.ma1.lines[0].array
188
+ ma2_array = self.ma2.lines[0].array
189
+ ppo_array = self.lines.ppo.array
190
+ signal_array = self.lines.signal.array
191
+ histo_array = self.lines.histo.array
192
+ signal_alpha = self.signal_alpha
193
+ signal_alpha1 = self.signal_alpha1
194
+ use_long = self._long
195
+
196
+ for arr in [ppo_array, signal_array, histo_array]:
197
+ while len(arr) < end:
198
+ arr.append(float("nan"))
199
+
200
+ prev_signal = 0.0
201
+ for i in range(start, min(end, len(ma1_array), len(ma2_array))):
202
+ ma1_val = ma1_array[i] if i < len(ma1_array) else 0.0
203
+ ma2_val = ma2_array[i] if i < len(ma2_array) else 0.0
204
+
205
+ if isinstance(ma1_val, float) and math.isnan(ma1_val):
206
+ ppo_array[i] = float("nan")
207
+ signal_array[i] = float("nan")
208
+ histo_array[i] = float("nan")
209
+ continue
210
+ if isinstance(ma2_val, float) and math.isnan(ma2_val):
211
+ ppo_array[i] = float("nan")
212
+ signal_array[i] = float("nan")
213
+ histo_array[i] = float("nan")
214
+ continue
215
+
216
+ po_val = ma1_val - ma2_val
217
+
218
+ den = ma2_val if use_long else ma1_val
219
+ if den != 0:
220
+ ppo_val = 100.0 * po_val / den
221
+ else:
222
+ ppo_val = 0.0
223
+ ppo_array[i] = ppo_val
224
+
225
+ # Update signal
226
+ if i > 0 and i - 1 < len(signal_array):
227
+ prev_val = signal_array[i - 1]
228
+ if not (isinstance(prev_val, float) and math.isnan(prev_val)):
229
+ prev_signal = prev_val
230
+
231
+ prev_signal = prev_signal * signal_alpha1 + ppo_val * signal_alpha
232
+ signal_array[i] = prev_signal
233
+
234
+ histo_array[i] = ppo_val - prev_signal
235
+
236
+
237
+ class PercentagePriceOscillatorShort(PercentagePriceOscillator):
238
+ """
239
+ Shows the difference between a short and long exponential moving
240
+ averages expressed in percentage. The MACD does the same but expressed in
241
+ absolute points.
242
+
243
+ Expressing the difference in percentage allows to compare the indicator at
244
+ different points in time when the underlying value has significatnly
245
+ different values.
246
+
247
+ Most on-line literature shows the percentage calculation having the long
248
+ exponential moving average as the denominator. Some sources like MetaStock
249
+ use the short one.
250
+
251
+ Formula:
252
+ - po = 100 * (ema(short) - ema(long)) / ema(short)
253
+
254
+ See:
255
+ - http://www.metastock.com/Customer/Resources/TAAZ/?c=3&p=94
256
+ """
257
+
258
+ _long = False
259
+ alias = (
260
+ "PPOShort",
261
+ "PercPriceOscShort",
262
+ )
@@ -0,0 +1,212 @@
1
+ #!/usr/bin/env python
2
+ """PSAR Indicator Module - Parabolic SAR.
3
+
4
+ This module provides the Parabolic SAR (Stop and Reverse) indicator
5
+ developed by J. Welles Wilder, Jr. for trend following and reversal signals.
6
+
7
+ Classes:
8
+ ParabolicSAR: Parabolic SAR indicator (alias: PSAR).
9
+
10
+ Example:
11
+ class MyStrategy(bt.Strategy):
12
+ def __init__(self):
13
+ self.psar = bt.indicators.PSAR(self.data)
14
+
15
+ def next(self):
16
+ # PSAR dots below price indicate uptrend
17
+ if self.psar.psar[0] < self.data.low[0]:
18
+ self.buy()
19
+ # PSAR dots above price indicate downtrend
20
+ elif self.psar.psar[0] > self.data.high[0]:
21
+ self.sell()
22
+ """
23
+
24
+ from . import PeriodN
25
+
26
+ __all__ = ["ParabolicSAR", "PSAR"]
27
+
28
+
29
+ class _SarStatus:
30
+ """Internal status holder for Parabolic SAR calculations.
31
+
32
+ Attributes:
33
+ sar: Stop and Reverse value for the current period.
34
+ tr: Trend direction (True for long/up, False for short/down).
35
+ af: Acceleration factor, controlling how quickly SAR responds.
36
+ ep: Extreme point - highest high in uptrend or lowest low in downtrend.
37
+ """
38
+
39
+ sar = None
40
+ tr = None
41
+ af = 0.0
42
+ ep = 0.0
43
+
44
+ def __str__(self):
45
+ """Return a string representation of the SAR status.
46
+
47
+ Returns:
48
+ str: Multi-line string containing sar, tr, af, and ep values.
49
+ """
50
+ txt = []
51
+ txt.append(f"sar: {self.sar}")
52
+ txt.append(f"tr: {self.tr}")
53
+ txt.append(f"af: {self.af}")
54
+ txt.append(f"ep: {self.ep}")
55
+ return "\n".join(txt)
56
+
57
+
58
+ class ParabolicSAR(PeriodN):
59
+ """Parabolic SAR (Stop and Reverse) indicator.
60
+
61
+ Defined by J. Welles Wilder, Jr. in 1978 in his book *New Concepts in
62
+ Technical Trading Systems*. SAR stands for Stop and Reverse, and the
63
+ indicator is meant as a signal for entry (and reverse).
64
+
65
+ The indicator places dots above or below price bars to indicate the
66
+ current trend direction. When the dots flip from above to below (or
67
+ vice versa), it signals a potential trend reversal.
68
+
69
+ The initial trend direction is determined by comparing the close price
70
+ of the second bar to the first bar. The SAR value accelerates toward
71
+ the price as the trend extends, using the acceleration factor.
72
+
73
+ See:
74
+ https://en.wikipedia.org/wiki/Parabolic_SAR
75
+ http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:parabolic_sar
76
+
77
+ Attributes:
78
+ psar: Line containing the calculated Parabolic SAR values.
79
+
80
+ Args:
81
+ period: Bar number from which to start showing values (default: 2).
82
+ af: Acceleration factor (default: 0.02).
83
+ afmax: Maximum acceleration factor (default: 0.20).
84
+ """
85
+
86
+ alias = ("PSAR",)
87
+ lines = ("psar",)
88
+ params = (
89
+ ("period", 2), # when to start showing values
90
+ ("af", 0.02),
91
+ ("afmax", 0.20),
92
+ )
93
+
94
+ plotinfo = {"subplot": False}
95
+ plotlines = {
96
+ "psar": {"marker": ".", "markersize": 4.0, "color": "black", "fillstyle": "full", "ls": ""},
97
+ }
98
+
99
+ def prenext(self):
100
+ """Handle calculations before minimum period is reached.
101
+
102
+ Initializes status tracking and calculates initial PSAR values.
103
+ """
104
+ if len(self) == 1:
105
+ self._status = [] # empty status
106
+ return # not enough data to do anything
107
+
108
+ if len(self) == 2:
109
+ self.nextstart() # kickstart calculation
110
+ else:
111
+ self.next() # regular calc
112
+
113
+ self.lines.psar[0] = float("NaN") # no return yet still prenext
114
+
115
+ def nextstart(self):
116
+ """Initialize PSAR calculation on first valid bar.
117
+
118
+ Determines initial trend direction and sets up status tracking.
119
+ """
120
+ if self._status: # some states have been calculated
121
+ self.next() # delegate
122
+ return
123
+
124
+ # Prepare a status holding array, for current and previous lengths
125
+ self._status = [_SarStatus(), _SarStatus()]
126
+
127
+ # Start by looking if price has gone up/down (close) in the 2nd day to
128
+ # get an *entry* signal and configure the values as they would have
129
+ # been in the previous trend, including a sar value which is
130
+ # immediately invalidated in next, which reverses and sets the trend to
131
+ # the actual up/down value calculated with the close
132
+ # Put the 4 status variables in a Status holder
133
+ plenidx = (len(self) - 1) % 2 # previous length index (0 or 1)
134
+ status = self._status[plenidx]
135
+
136
+ # Calculate the status for previous length
137
+ status.sar = (self.data.high[0] + self.data.low[0]) / 2.0
138
+
139
+ status.af = self.p.af
140
+ if self.data.close[0] >= self.data.close[-1]: # uptrend
141
+ status.tr = not True # uptrend when reversed
142
+ status.ep = self.data.low[-1] # ep from prev trend
143
+ else:
144
+ status.tr = not False # downtrend when reversed
145
+ status.ep = self.data.high[-1] # ep from prev trend
146
+
147
+ # With the fake prev trend in place and a sar which will be invalidated
148
+ # go to next to get the calculation done
149
+ self.next()
150
+
151
+ def next(self):
152
+ """Calculate PSAR for the current bar.
153
+
154
+ Updates the stop-and-reverse point based on trend direction,
155
+ extreme price, and acceleration factor.
156
+ """
157
+ hi = self.data.high[0]
158
+ lo = self.data.low[0]
159
+
160
+ plenidx = (len(self) - 1) % 2 # previous length index (0 or 1)
161
+ status = self._status[plenidx] # use prev status for calculations
162
+
163
+ tr = status.tr
164
+ sar = status.sar
165
+
166
+ # Check if the sar penetrated the price to switch the trend
167
+ if (tr and sar >= lo) or (not tr and sar <= hi):
168
+ tr = not tr # reverse the trend
169
+ sar = status.ep # new sar is prev SIP (Significant price)
170
+ ep = hi if tr else lo # select new SIP / Extreme Price
171
+ af = self.p.af # reset acceleration factor
172
+
173
+ else: # use the precalculated values
174
+ ep = status.ep
175
+ af = status.af
176
+
177
+ # Update sar value for today
178
+ self.lines.psar[0] = sar
179
+
180
+ # Update ep and af if needed
181
+ if tr: # long trade
182
+ if hi > ep:
183
+ ep = hi
184
+ af = min(af + self.p.af, self.p.afmax)
185
+
186
+ else: # downtrend
187
+ if lo < ep:
188
+ ep = lo
189
+ af = min(af + self.p.af, self.p.afmax)
190
+
191
+ sar = sar + af * (ep - sar) # calculate the sar for tomorrow
192
+
193
+ # make sure sar doesn't go into hi/lows
194
+ if tr: # long trade
195
+ lo1 = self.data.low[-1]
196
+ if sar > lo or sar > lo1:
197
+ sar = min(lo, lo1) # sar not above last 2 lows -> lower
198
+ else:
199
+ hi1 = self.data.high[-1]
200
+ if sar < hi or sar < hi1:
201
+ sar = max(hi, hi1) # sar not below last 2 highs -> highest
202
+
203
+ # new status has been calculated, keep it in current length
204
+ # will be used when length moves forward
205
+ newstatus = self._status[not plenidx]
206
+ newstatus.tr = tr
207
+ newstatus.sar = sar
208
+ newstatus.ep = ep
209
+ newstatus.af = af
210
+
211
+
212
+ PSAR = ParabolicSAR
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env python
2
+ """Relative Momentum Index Module - RMI indicator.
3
+
4
+ This module provides the Relative Momentum Index (RMI) developed by
5
+ Roger Altman as a variation of RSI.
6
+
7
+ Classes:
8
+ RelativeMomentumIndex: RMI indicator (alias: RMI).
9
+
10
+ Example:
11
+ class MyStrategy(bt.Strategy):
12
+ def __init__(self):
13
+ self.rmi = bt.indicators.RMI(self.data, period=20, lookback=5)
14
+
15
+ def next(self):
16
+ # RMI above 70 indicates overbought
17
+ if self.rmi.rmi[0] > 70:
18
+ self.sell()
19
+ # RMI below 30 indicates oversold
20
+ elif self.rmi.rmi[0] < 30:
21
+ self.buy()
22
+ """
23
+
24
+ from . import RSI
25
+
26
+
27
+ class RelativeMomentumIndex(RSI):
28
+ """
29
+ Description:
30
+ The Relative Momentum Index was developed by Roger Altman and was
31
+ introduced in his article in the February 1993 issue of Technical Analysis
32
+ of Stocks & Commodities magazine.
33
+
34
+ While your typical RSI counts up and down days from close to close, the
35
+ Relative Momentum Index counts up and down days from the close relative to
36
+ a close x number of days ago. The result is an RSI that is a bit smoother.
37
+
38
+ Usage:
39
+ Use in the same way you would any other RSI. There are overbought and
40
+ oversold zones, and can also be used for divergence and trend analysis.
41
+
42
+ See:
43
+ - https://www.marketvolume.com/technicalanalysis/relativemomentumindex.asp
44
+ - https://www.tradingview.com/script/UCm7fIvk-FREE-INDICATOR-Relative-Momentum-Index-RMI/
45
+ - https://www.prorealcode.com/prorealtime-indicators/relative-momentum-index-rmi/
46
+
47
+ """
48
+
49
+ alias = ("RMI",)
50
+
51
+ linealias = (
52
+ (
53
+ "rsi",
54
+ "rmi",
55
+ ),
56
+ ) # add an alias for this class rmi -> rsi
57
+ plotlines = {"rsi": {"_name": "rmi"}} # change line plotting name
58
+
59
+ params = (
60
+ ("period", 20),
61
+ ("lookback", 5),
62
+ )
63
+
64
+ def _plotlabel(self):
65
+ # override to always print the lookback label and do it before movav
66
+ plabels = [self.p.period]
67
+ plabels += [self.p.lookback]
68
+ plabels += [self.p.movav] * self.p.notdefault("movav")
69
+ return plabels