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,179 @@
1
+ #!/usr/bin/env python
2
+ """Custom Indicators Module - User-defined indicators.
3
+
4
+ This module contains custom indicator algorithms including:
5
+ - MaBetweenHighAndLow: Check if MA is within price range
6
+ - BarsLast: Count bars since condition was met
7
+ - NewDiff: Guotai Junan alpha factor indicator
8
+
9
+ Example:
10
+ To use these custom indicators in your strategy::
11
+
12
+ import backtrader as bt
13
+
14
+ class MyStrategy(bt.Strategy):
15
+ def __init__(self):
16
+ # Create MA Between High and Low indicator
17
+ self.ma_hl = bt.indicators.MaBetweenHighAndLow(
18
+ self.data, period=5
19
+ )
20
+
21
+ # Create Bars Last indicator
22
+ self.bars_last = bt.indicators.BarsLast(
23
+ self.data, period=5
24
+ )
25
+
26
+ # Create NewDiff indicator (Guotai Junan alpha factor)
27
+ self.new_diff = bt.indicators.NewDiff(
28
+ self.data, period=6
29
+ )
30
+
31
+ def next(self):
32
+ # Use the indicators in your trading logic
33
+ if self.ma_hl.target[0] > 0:
34
+ # MA is within high-low range
35
+ self.buy()
36
+
37
+ if self.bars_last.bar_num[0] < 3:
38
+ # Condition was met less than 3 bars ago
39
+ self.sell()
40
+
41
+ # Access the alpha factor value
42
+ alpha_value = self.new_diff.factor[0]
43
+ """
44
+
45
+ import math
46
+
47
+ import numpy as np
48
+
49
+ from . import SMA, If, Indicator, Max, Min
50
+
51
+ # This file contains some custom indicator algorithms
52
+
53
+
54
+ class MaBetweenHighAndLow(Indicator):
55
+ """Check if moving average is between high and low prices.
56
+
57
+ Returns 1.0 when SMA is within the bar's high-low range,
58
+ 0.0 otherwise.
59
+ """
60
+
61
+ # Check if moving average is between high and low prices
62
+ lines = ("target",)
63
+ params = (("period", 5),)
64
+
65
+ def __init__(self):
66
+ """Initialize the MA Between High and Low indicator.
67
+
68
+ Creates SMA for comparison with high/low range.
69
+ """
70
+ super().__init__()
71
+ self.ma = SMA(self.data.close, period=self.p.period)
72
+
73
+ def next(self):
74
+ """Check if MA is between high and low for current bar.
75
+
76
+ Returns 1.0 if MA is within range, 0.0 otherwise.
77
+ """
78
+ ma_val = self.ma[0]
79
+ high_val = self.data.high[0]
80
+ low_val = self.data.low[0]
81
+ self.lines.target[0] = 1.0 if (ma_val < high_val and ma_val > low_val) else 0.0
82
+
83
+ def once(self, start, end):
84
+ """Check MA against high/low range in runonce mode.
85
+
86
+ Returns 1.0 where MA is within range, 0.0 otherwise.
87
+ """
88
+ ma_array = self.ma.lines[0].array
89
+ high_array = self.data.high.array
90
+ low_array = self.data.low.array
91
+ larray = self.lines.target.array
92
+
93
+ while len(larray) < end:
94
+ larray.append(float("nan"))
95
+
96
+ for i in range(start, min(end, len(ma_array), len(high_array), len(low_array))):
97
+ ma_val = ma_array[i] if i < len(ma_array) else 0.0
98
+ high_val = high_array[i] if i < len(high_array) else 0.0
99
+ low_val = low_array[i] if i < len(low_array) else 0.0
100
+
101
+ if isinstance(ma_val, float) and math.isnan(ma_val):
102
+ larray[i] = float("nan")
103
+ else:
104
+ larray[i] = 1.0 if (ma_val < high_val and ma_val > low_val) else 0.0
105
+
106
+
107
+ class BarsLast(Indicator):
108
+ """Count bars since condition was last met.
109
+
110
+ Tracks the number of bars that have passed since a specified
111
+ condition (default: MaBetweenHighAndLow) was last true.
112
+ """
113
+
114
+ # This indicator analyzes the number of bars since the last condition was met
115
+ lines = ("bar_num",)
116
+ params = (("period", 5), ("func", MaBetweenHighAndLow))
117
+
118
+ def __init__(self):
119
+ """Initialize the Bars Last indicator.
120
+
121
+ Creates target function for condition checking.
122
+ """
123
+ self.target = self.p.func(self.data, period=self.p.period)
124
+ self.num = np.nan
125
+
126
+ def next(self):
127
+ """Count bars since condition was last met.
128
+
129
+ Resets to 0 when condition is true, increments otherwise.
130
+ """
131
+ if self.target[0]:
132
+ self.num = 0
133
+ self.lines.bar_num[0] = self.num
134
+ self.num = self.num + 1
135
+
136
+
137
+ class NewDiff(Indicator):
138
+ """Guotai Junan alpha factor indicator.
139
+
140
+ Calculates a proprietary alpha factor based on price movement
141
+ relative to previous close and the high/low range.
142
+
143
+ Formula:
144
+ SUM((CLOSE==DELAY(CLOSE,1)?0:CLOSE-(CLOSE>DELAY(CLOSE,1)?
145
+ MIN(LOW,DELAY(CLOSE,1)):MAX(HIGH,DELAY(CLOSE,1)))), period)
146
+ """
147
+
148
+ # Indicator based on Guotai Junan alpha factor
149
+ # : SUM((CLOSE=DELAY(CLOSE,1)?0:CLOSE-(CLOSE>DELAY(CLOSE,1)?MIN(LOW,DELAY(CLOSE,1)):MAX(HIGH,DELAY(CLOSE,1)))),6)
150
+ # - e = MIN(LOW, DELAY(CLOSE, 1))
151
+ # - f = MAX(HIGH, DELAY(CLOSE, 1))
152
+ # - h = CLOSE > DELAY(CLOSE, 1)
153
+ # - b = h?e: f
154
+ # - a = CLOSE = DELAY(CLOSE, 1)?0: CLOSE - b
155
+ # - c = SUM(a, 6)
156
+ lines = ("factor",)
157
+ params = (("period", 5),)
158
+
159
+ def __init__(self):
160
+ """Initialize the NewDiff indicator.
161
+
162
+ Sets up alpha factor calculation based on Guotai Junan formula.
163
+ """
164
+ close = self.data.close
165
+ pre_close = self.data.close(-1)
166
+ e = Min(self.data.low, pre_close)
167
+ f = Max(self.data.high, pre_close)
168
+ b = If(close > pre_close, e, f)
169
+ self.a = If(close == pre_close, 0, close - b)
170
+
171
+ def next(self):
172
+ """Calculate NewDiff factor for the current bar.
173
+
174
+ Sums adjusted price differences over the period.
175
+ """
176
+ if len(self.a) >= self.p.period:
177
+ self.lines.factor[0] = math.fsum(self.a.get(size=self.p.period))
178
+ else:
179
+ self.lines.factor[0] = np.nan
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env python
2
+ """On-Balance Volume indicator.
3
+
4
+ This module provides the On-Balance Volume (OBV) cumulative volume indicator.
5
+ OBV adds the current volume when the closing price rises, subtracts it when
6
+ it falls, and leaves the cumulative value unchanged when the closing price is
7
+ unchanged.
8
+
9
+ Classes:
10
+ OnBalanceVolume: On-Balance Volume indicator (alias: OBV).
11
+
12
+ Example:
13
+ class MyStrategy(bt.Strategy):
14
+ def __init__(self):
15
+ self.obv = bt.indicators.OBV(self.data)
16
+ """
17
+
18
+ from . import Indicator
19
+
20
+
21
+ class OnBalanceVolume(Indicator):
22
+ """Cumulative On-Balance Volume indicator.
23
+
24
+ Formula:
25
+ - first value = volume
26
+ - close > previous close: obv = previous obv + volume
27
+ - close < previous close: obv = previous obv - volume
28
+ - close == previous close: obv = previous obv
29
+ """
30
+
31
+ alias = ("OBV",)
32
+ lines = ("obv",)
33
+
34
+ def __init__(self):
35
+ """Initialize the indicator."""
36
+ super().__init__()
37
+
38
+ def nextstart(self):
39
+ """Seed OBV with the first available volume value."""
40
+ self.lines.obv[0] = self.data.volume[0]
41
+
42
+ def next(self):
43
+ """Update OBV for the current bar in event-driven mode."""
44
+ previous = self.lines.obv[-1]
45
+ close = self.data.close[0]
46
+ previous_close = self.data.close[-1]
47
+ volume = self.data.volume[0]
48
+
49
+ if close > previous_close:
50
+ self.lines.obv[0] = previous + volume
51
+ elif close < previous_close:
52
+ self.lines.obv[0] = previous - volume
53
+ else:
54
+ self.lines.obv[0] = previous
55
+
56
+ def oncestart(self, start, end):
57
+ """Seed OBV in batch-processing mode."""
58
+ dst = self.lines.obv.array
59
+ volume = self.data.volume.array
60
+
61
+ while len(dst) < end:
62
+ dst.append(float("nan"))
63
+
64
+ for i in range(start, min(end, len(volume))):
65
+ dst[i] = volume[i]
66
+
67
+ def once(self, start, end):
68
+ """Calculate OBV values in batch-processing mode."""
69
+ dst = self.lines.obv.array
70
+ close = self.data.close.array
71
+ volume = self.data.volume.array
72
+ actual_end = min(end, len(close), len(volume))
73
+
74
+ while len(dst) < end:
75
+ dst.append(float("nan"))
76
+
77
+ if start >= actual_end:
78
+ return
79
+
80
+ if start == 0:
81
+ dst[0] = volume[0]
82
+ start = 1
83
+
84
+ previous = dst[start - 1]
85
+ for i in range(start, actual_end):
86
+ if close[i] > close[i - 1]:
87
+ previous += volume[i]
88
+ elif close[i] < close[i - 1]:
89
+ previous -= volume[i]
90
+
91
+ dst[i] = previous
92
+
93
+
94
+ OBV = OnBalanceVolume
@@ -0,0 +1,265 @@
1
+ #!/usr/bin/env python
2
+ """OLS Indicator Module - Ordinary least squares regression.
3
+
4
+ This module provides indicators using OLS (Ordinary Least Squares)
5
+ regression for statistical analysis.
6
+
7
+ Classes:
8
+ OLS_Slope_InterceptN: Calculates slope and intercept via OLS.
9
+ OLS_TransformationN: Calculates OLS transformed values.
10
+ OLS_BetaN: Calculates beta via OLS.
11
+ CointN: Tests for cointegration between series.
12
+
13
+ Example:
14
+ class MyStrategy(bt.Strategy):
15
+ def __init__(self):
16
+ # Calculate OLS regression slope and intercept between two data feeds
17
+ self.ols = bt.indicators.OLS_Slope_InterceptN(self.data0, self.data1, period=30)
18
+
19
+ # Calculate OLS transformation (spread, zscore)
20
+ self.ols_trans = bt.indicators.OLS_TransformationN(self.data0, self.data1, period=30)
21
+
22
+ def next(self):
23
+ # Trade based on zscore of the spread
24
+ if self.ols_trans.zscore[0] > 2:
25
+ # Spread is too high - short data0, long data1
26
+ self.sell(data=self.data0)
27
+ self.buy(data=self.data1)
28
+ elif self.ols_trans.zscore[0] < -2:
29
+ # Spread is too low - long data0, short data1
30
+ self.buy(data=self.data0)
31
+ self.sell(data=self.data1)
32
+ """
33
+
34
+ import pandas as pd
35
+
36
+ from . import PeriodN
37
+
38
+ # Lazy import statsmodels to avoid slow import at module load time
39
+ # statsmodels is a heavy library that adds 20+ seconds to import time
40
+ # It will be imported when the indicators are actually used
41
+
42
+
43
+ def _get_statsmodels():
44
+ """Lazy import statsmodels.api."""
45
+ import statsmodels.api as sm
46
+
47
+ return sm
48
+
49
+
50
+ def _get_coint():
51
+ """Lazy import statsmodels coint function."""
52
+ from statsmodels.tsa.stattools import coint
53
+
54
+ return coint
55
+
56
+
57
+ __all__ = ["OLS_Slope_InterceptN", "OLS_TransformationN", "OLS_BetaN", "CointN"]
58
+
59
+
60
+ class OLS_Slope_InterceptN(PeriodN):
61
+ """
62
+ Calculates a linear regression using ``statsmodel.OLS`` (Ordinary least
63
+ squares) of data1 on data0
64
+
65
+ Uses ``pandas`` and ``statsmodels``
66
+ """
67
+
68
+ _mindatas = 2 # ensure at least 2 data feeds are passed
69
+
70
+ packages = (
71
+ ("pandas", "pd"),
72
+ ("statsmodels.api", "sm"),
73
+ )
74
+ lines = (
75
+ "slope",
76
+ "intercept",
77
+ )
78
+ params = (("period", 10),)
79
+
80
+ def next(self):
81
+ """Calculate OLS slope and intercept for the current bar.
82
+
83
+ Uses statsmodels OLS to perform linear regression.
84
+ """
85
+ sm = _get_statsmodels()
86
+ p0 = pd.Series(self.data0.get(size=self.p.period))
87
+ p1 = pd.Series(self.data1.get(size=self.p.period))
88
+ p1 = sm.add_constant(p1)
89
+ intercept, slope = sm.OLS(p0, p1).fit().params
90
+
91
+ self.lines.slope[0] = slope
92
+ self.lines.intercept[0] = intercept
93
+
94
+
95
+ class OLS_TransformationN(PeriodN):
96
+ """
97
+ Calculates the ``zscore`` for data0 and data1. Although it doesn't directly
98
+ use any external package, it relies on ``OLS_SlopeInterceptN`` which uses
99
+ ``pandas`` and ``statsmodels``
100
+ """
101
+
102
+ _mindatas = 2 # ensure at least 2 data feeds are passed
103
+ lines = (
104
+ "spread",
105
+ "spread_mean",
106
+ "spread_std",
107
+ "zscore",
108
+ )
109
+ params = (("period", 10),)
110
+
111
+ def __init__(self):
112
+ """Initialize the OLS Transformation indicator.
113
+
114
+ Creates OLS slope-intercept indicator for transformation calculations.
115
+ """
116
+ super().__init__()
117
+ self.slint = OLS_Slope_InterceptN(*self.datas)
118
+
119
+ def next(self):
120
+ """Calculate OLS transformation values for the current bar.
121
+
122
+ Computes spread, mean, std, and zscore based on OLS regression.
123
+ """
124
+ slope = self.slint.slope[0]
125
+ intercept = self.slint.intercept[0]
126
+ spread = self.data0[0] - (slope * self.data1[0] + intercept)
127
+ self.lines.spread[0] = spread
128
+
129
+ # Calculate spread_mean (SMA of spread)
130
+ period = self.p.period
131
+ spread_sum = spread
132
+ for i in range(1, period):
133
+ spread_sum += self.lines.spread[-i]
134
+ spread_mean = spread_sum / period
135
+ self.lines.spread_mean[0] = spread_mean
136
+
137
+ # Calculate spread_std (StdDev of spread)
138
+ var_sum = (spread - spread_mean) ** 2
139
+ for i in range(1, period):
140
+ var_sum += (self.lines.spread[-i] - spread_mean) ** 2
141
+ spread_std = (var_sum / period) ** 0.5
142
+ self.lines.spread_std[0] = spread_std
143
+
144
+ # Calculate zscore
145
+ if spread_std != 0:
146
+ self.lines.zscore[0] = (spread - spread_mean) / spread_std
147
+ else:
148
+ self.lines.zscore[0] = 0.0
149
+
150
+ def once(self, start, end):
151
+ """Calculate OLS transformation in runonce mode.
152
+
153
+ Computes spread, mean, std, and zscore values across all bars.
154
+ """
155
+
156
+ slope_array = self.slint.lines.slope.array
157
+ intercept_array = self.slint.lines.intercept.array
158
+ d0_array = self.data0.array
159
+ d1_array = self.data1.array
160
+ spread_array = self.lines.spread.array
161
+ mean_array = self.lines.spread_mean.array
162
+ std_array = self.lines.spread_std.array
163
+ zscore_array = self.lines.zscore.array
164
+ period = self.p.period
165
+
166
+ for arr in [spread_array, mean_array, std_array, zscore_array]:
167
+ while len(arr) < end:
168
+ arr.append(float("nan"))
169
+
170
+ # Calculate spread
171
+ for i in range(
172
+ start, min(end, len(slope_array), len(intercept_array), len(d0_array), len(d1_array))
173
+ ):
174
+ slope = slope_array[i] if i < len(slope_array) else 0.0
175
+ intercept = intercept_array[i] if i < len(intercept_array) else 0.0
176
+ d0 = d0_array[i] if i < len(d0_array) else 0.0
177
+ d1 = d1_array[i] if i < len(d1_array) else 0.0
178
+ spread_array[i] = d0 - (slope * d1 + intercept)
179
+
180
+ # Calculate spread_mean, spread_std, zscore
181
+ for i in range(start, min(end, len(spread_array))):
182
+ if i < period - 1:
183
+ mean_array[i] = float("nan")
184
+ std_array[i] = float("nan")
185
+ zscore_array[i] = float("nan")
186
+ else:
187
+ spread_sum = 0.0
188
+ for j in range(period):
189
+ idx = i - j
190
+ if idx >= 0 and idx < len(spread_array):
191
+ spread_sum += spread_array[idx]
192
+ spread_mean = spread_sum / period
193
+ mean_array[i] = spread_mean
194
+
195
+ var_sum = 0.0
196
+ for j in range(period):
197
+ idx = i - j
198
+ if idx >= 0 and idx < len(spread_array):
199
+ var_sum += (spread_array[idx] - spread_mean) ** 2
200
+ spread_std = (var_sum / period) ** 0.5
201
+ std_array[i] = spread_std
202
+
203
+ spread = spread_array[i]
204
+ if spread_std != 0:
205
+ zscore_array[i] = (spread - spread_mean) / spread_std
206
+ else:
207
+ zscore_array[i] = 0.0
208
+
209
+
210
+ class OLS_BetaN(PeriodN):
211
+ """
212
+ Calculates a regression of data1 on data0 using ``pandas.ols``
213
+
214
+ Uses ``pandas``
215
+ """
216
+
217
+ _mindatas = 2 # ensure at least 2 data feeds are passed
218
+
219
+ packages = (("pandas", "pd"),)
220
+
221
+ lines = ("beta",)
222
+ params = (("period", 10),)
223
+
224
+ def next(self):
225
+ """Calculate beta via OLS regression for the current bar.
226
+
227
+ Uses pandas OLS to calculate regression beta.
228
+ """
229
+ y, x = (pd.Series(d.get(size=self.p.period)) for d in self.datas)
230
+ r_beta = pd.ols(y=y, x=x, window_type="full_sample")
231
+ self.lines.beta[0] = r_beta.beta["x"]
232
+
233
+
234
+ class CointN(PeriodN):
235
+ """
236
+ Calculates the score (coint_t) and pvalue for a given ``period`` for the
237
+ data feeds
238
+
239
+ Uses ``pandas`` and ``statsmodels`` (for ``coint``)
240
+ """
241
+
242
+ _mindatas = 2 # ensure at least 2 data feeds are passed
243
+
244
+ packages = (("pandas", "pd"),) # import pandas as pd
245
+ frompackages = (("statsmodels.tsa.stattools", "coint"),) # from st... import coint
246
+
247
+ lines = (
248
+ "score",
249
+ "pvalue",
250
+ )
251
+ params = (
252
+ ("period", 10),
253
+ ("trend", "c"), # see statsmodel.tsa.statttools
254
+ )
255
+
256
+ def next(self):
257
+ """Calculate cointegration test for the current period.
258
+
259
+ Uses statsmodels coint function to test for cointegration.
260
+ """
261
+ coint = _get_coint()
262
+ x, y = (pd.Series(d.get(size=self.p.period)) for d in self.datas)
263
+ score, pvalue, _ = coint(x, y, trend=self.p.trend)
264
+ self.lines.score[0] = score
265
+ self.lines.pvalue[0] = pvalue
@@ -0,0 +1,161 @@
1
+ #!/usr/bin/env python
2
+ """Oscillator Indicator Module - Oscillating indicators.
3
+
4
+ This module provides oscillator indicators that show the deviation
5
+ of one data series from another, typically price from a moving average.
6
+
7
+ Classes:
8
+ OscillatorMixIn: MixIn class to create oscillating indicators.
9
+ Oscillator: Oscillation of data around another data.
10
+
11
+ Example:
12
+ class MyStrategy(bt.Strategy):
13
+ def __init__(self):
14
+ # Oscillate price around SMA
15
+ self.osc = bt.indicators.Oscillator(self.data, bt.indicators.SMA(self.data, period=20))
16
+
17
+ def next(self):
18
+ # When oscillator is positive, price is above SMA
19
+ if self.osc[0] > 0:
20
+ self.buy()
21
+ elif self.osc[0] < 0:
22
+ self.sell()
23
+ """
24
+
25
+ import sys
26
+
27
+ from ..utils.log_message import get_logger
28
+ from . import Indicator, MovingAverage
29
+
30
+ logger = get_logger(__name__)
31
+
32
+
33
+ class OscillatorMixIn(Indicator):
34
+ """
35
+ MixIn class to create a subclass with another indicator. The main line of
36
+ that indicator will be substracted from the other base class main line
37
+ creating an oscillator
38
+
39
+ The usage is:
40
+
41
+ - Class XXXOscillator(XXX, OscillatorMixIn)
42
+
43
+ Formula:
44
+ - XXX calculates lines[0]
45
+ - osc = self.data - XXX.lines[0]
46
+ """
47
+
48
+ plotlines = {"_0": {"_name": "osc"}}
49
+
50
+ def _plotinit(self):
51
+ try:
52
+ lname = self.lines._getlinealias(0)
53
+ self.plotlines._0._name = lname + "_osc"
54
+ except AttributeError:
55
+ # No line alias available; keep the default plot label.
56
+ logger.debug("oscillator:55 ignored AttributeError")
57
+
58
+ def __init__(self):
59
+ """Initialize the oscillator by subtracting the base line from data."""
60
+ self.lines[0] = self.data - self.lines[0]
61
+ super().__init__()
62
+
63
+
64
+ class Oscillator(Indicator):
65
+ """
66
+ Oscillation of given data around another data
67
+
68
+ Datas:
69
+ This indicator can accept one or two data for the calculation.
70
+
71
+ - If one data is provided, it must be a complex "Lines" object (indicator)
72
+ which also has "data".Example: A moving average
73
+
74
+ The calculated oscillation will be that of the Moving Average (in the
75
+ example) around the data that was used for the average calculation
76
+
77
+ - If two data are provided, the calculated oscillation will be that of the
78
+ second data around the first data
79
+
80
+ Formula:
81
+ - 1 data -> osc = data.data - data
82
+ - 2 datas -> osc = data0 - data1
83
+ """
84
+
85
+ lines = ("osc",)
86
+
87
+ # Have a default value which can be later modified if needed
88
+ plotlines = {"_0": {"_name": "osc"}}
89
+
90
+ def _plotinit(self):
91
+ try:
92
+ lname = self.dataosc._getlinealias(0)
93
+ self.plotlines._0._name = lname + "_osc"
94
+ except AttributeError:
95
+ # No line alias available; keep the default plot label.
96
+ logger.debug("oscillator:95 ignored AttributeError")
97
+
98
+ def __init__(self):
99
+ """Initialize the oscillator with data source and oscillator data.
100
+
101
+ Calculates the oscillation between two data series or between
102
+ a data series and its underlying data.
103
+ """
104
+ super().__init__()
105
+
106
+ if len(self.datas) > 1:
107
+ datasrc = self.data
108
+ self.dataosc = self.data1
109
+ else:
110
+ datasrc = self.data.data
111
+ self.dataosc = self.data
112
+
113
+ self.lines[0] = datasrc - self.dataosc
114
+
115
+
116
+ # Automatic creation of Oscillating Lines
117
+
118
+ for movav in MovingAverage._movavs[0:]:
119
+ _newclsdoc = """
120
+ Oscillation of a %s around its data
121
+ """
122
+ # Skip aliases - they will be created automatically
123
+ if getattr(movav, "aliased", ""):
124
+ continue
125
+
126
+ movname = movav.__name__
127
+ # Handle both tuple lines and Lines objects after refactoring
128
+ if hasattr(movav.lines, "_getlinealias"):
129
+ # It's a Lines object
130
+ linename = movav.lines._getlinealias(0)
131
+ elif isinstance(movav.lines, (tuple, list)) and movav.lines:
132
+ # It's a tuple/list of line names
133
+ linename = movav.lines[0]
134
+ else:
135
+ # Fallback to first line name or class name. The lambda is invoked
136
+ # immediately within this loop iteration (no late binding), so B023 is
137
+ # a false positive here.
138
+ linename = (
139
+ getattr(movav.lines, "_getlinealias", lambda x: movav.__name__.lower())(0) # noqa: B023
140
+ if hasattr(movav.lines, "_getlinealias")
141
+ else movav.__name__.lower()
142
+ )
143
+
144
+ newclsname = movname + "Oscillator"
145
+
146
+ newaliases = [movname + "Osc"]
147
+ for alias in getattr(movav, "alias", []):
148
+ for suffix in ["Oscillator", "Osc"]:
149
+ newaliases.append(alias + suffix)
150
+
151
+ newclsdoc = _newclsdoc % movname
152
+ newclsdct = {
153
+ "__doc__": newclsdoc,
154
+ "__module__": OscillatorMixIn.__module__,
155
+ "_notregister": True,
156
+ "alias": newaliases,
157
+ }
158
+
159
+ newcls = type(str(newclsname), (movav, OscillatorMixIn), newclsdct)
160
+ module = sys.modules[OscillatorMixIn.__module__]
161
+ setattr(module, newclsname, newcls)