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,106 @@
1
+ #!/usr/bin/env python
2
+ """Functional-test indicators migrated to contrib.
3
+
4
+ Generated from a single functional strategy module to preserve file-local
5
+ helper functions and constants without cross-test name collisions.
6
+ """
7
+
8
+ import math
9
+
10
+ from .. import Indicator
11
+
12
+ __all__ = [
13
+ "LsmaAngleIndicator",
14
+ ]
15
+
16
+
17
+ class LsmaAngleIndicator(Indicator):
18
+ """Compute LSMA slope angle and map it to a color-state indicator.
19
+
20
+ The indicator evaluates two least-squares MAs at different shifts and uses
21
+ the angle and trend persistence to classify bullish/bearish momentum states.
22
+
23
+ Args:
24
+ lsma_period: Look-back window used for each LSMA estimate.
25
+ angle_threshold: Threshold used to classify the angle magnitude.
26
+ start_shift: Shift index for the start LSMA sample.
27
+ end_shift: Shift index for the end LSMA sample.
28
+ """
29
+
30
+ lines = ("angle", "color_index")
31
+ params = (
32
+ ("lsma_period", 25),
33
+ ("angle_threshold", 15),
34
+ ("start_shift", 4),
35
+ ("end_shift", 0),
36
+ )
37
+
38
+ def __init__(self):
39
+ """Set minimum-history requirement and initialize derived scale factor."""
40
+ needed = (
41
+ int(max(self.p.lsma_period + self.p.start_shift, self.p.lsma_period + self.p.end_shift))
42
+ + 2
43
+ )
44
+ self.addminperiod(needed)
45
+ self._m_factor = None
46
+
47
+ def _lsma(self, shift):
48
+ period = int(self.p.lsma_period)
49
+ values = [float(self.data.close[-(shift + i)]) for i in range(period)]
50
+ x = list(range(period))
51
+ x_mean = sum(x) / period
52
+ y_mean = sum(values) / period
53
+ numerator = sum((xi - x_mean) * (yi - y_mean) for xi, yi in zip(x, values))
54
+ denominator = sum((xi - x_mean) ** 2 for xi in x)
55
+ slope = numerator / denominator if denominator else 0.0
56
+ intercept = y_mean - slope * x_mean
57
+ return intercept + slope * (period - 1)
58
+
59
+ def _ensure_factor(self):
60
+ if self._m_factor is not None:
61
+ return
62
+ point = (
63
+ float(getattr(self.data, "_dataname", None).attrs["point"])
64
+ if hasattr(getattr(self.data, "_dataname", None), "attrs")
65
+ and "point" in self.data._dataname.attrs
66
+ else None
67
+ )
68
+ if point is None or point <= 0:
69
+ close0 = float(self.data.close[0]) if len(self.data) else 0.0
70
+ point = 0.01 if abs(close0) >= 10 and abs(close0) < 1000 else 0.0001
71
+ shift_diff = float(int(self.p.start_shift) - int(self.p.end_shift))
72
+ self._m_factor = (
73
+ 1000.0
74
+ if abs(float(self.data.close[0])) >= 10 and abs(float(self.data.close[0])) < 1000
75
+ else 100000.0
76
+ ) / shift_diff
77
+
78
+ def next(self):
79
+ """Calculate the current angle and update color index for the next bar."""
80
+ if int(self.p.end_shift) >= int(self.p.start_shift):
81
+ self.lines.angle[0] = 0.0
82
+ self.lines.color_index[0] = 2
83
+ return
84
+ self._ensure_factor()
85
+ end_ma = self._lsma(int(self.p.end_shift))
86
+ start_ma = self._lsma(int(self.p.start_shift))
87
+ angle = self._m_factor * (end_ma - start_ma) / 2.0
88
+ self.lines.angle[0] = angle
89
+ clr = 2
90
+ threshold = float(self.p.angle_threshold)
91
+ prev_angle = (
92
+ float(self.lines.angle[-1])
93
+ if len(self) > 0 and math.isfinite(float(self.lines.angle[-1]))
94
+ else angle
95
+ )
96
+ if angle > threshold:
97
+ if angle > prev_angle:
98
+ clr = 4
99
+ elif angle < prev_angle:
100
+ clr = 3
101
+ if angle < -threshold:
102
+ if angle < prev_angle:
103
+ clr = 0
104
+ elif angle > prev_angle:
105
+ clr = 1
106
+ self.lines.color_index[0] = clr
@@ -0,0 +1,149 @@
1
+ #!/usr/bin/env python
2
+ """Functional-test indicators migrated to contrib.
3
+
4
+ Generated from a single functional strategy module to preserve file-local
5
+ helper functions and constants without cross-test name collisions.
6
+ """
7
+
8
+ from .. import (
9
+ ATR,
10
+ EMA,
11
+ SMA,
12
+ Indicator,
13
+ SmoothedMovingAverage,
14
+ WeightedMovingAverage,
15
+ )
16
+
17
+ __all__ = [
18
+ "MARoundingChannelIndicator",
19
+ ]
20
+
21
+
22
+ def resolve_ma_class(name):
23
+ """Map MA method name to the corresponding Backtrader indicator class."""
24
+ mode = str(name).lower()
25
+ if mode in {"sma", "mode_sma"}:
26
+ return SMA
27
+ if mode in {"ema", "mode_ema"}:
28
+ return EMA
29
+ if mode in {"smma", "mode_smma"}:
30
+ return SmoothedMovingAverage
31
+ return WeightedMovingAverage
32
+
33
+
34
+ def resolve_price_line(data, mode):
35
+ """Map a configured price selector string to feed line values."""
36
+ price_mode = str(mode).lower()
37
+ if price_mode in {"price_open", "open"}:
38
+ return data.open
39
+ if price_mode in {"price_high", "high"}:
40
+ return data.high
41
+ if price_mode in {"price_low", "low"}:
42
+ return data.low
43
+ if price_mode in {"price_median", "median"}:
44
+ return (data.high + data.low) / 2.0
45
+ if price_mode in {"price_typical", "typical"}:
46
+ return (data.high + data.low + data.close) / 3.0
47
+ if price_mode in {"price_weighted", "weighted"}:
48
+ return (data.high + data.low + data.close + data.close) / 4.0
49
+ if price_mode in {"price_simpl", "simpl"}:
50
+ return (data.open + data.close) / 2.0
51
+ if price_mode in {"price_quarter", "quarter"}:
52
+ return (data.high + data.low + data.open + data.close) / 4.0
53
+ if price_mode in {"price_trendfollow0", "trendfollow0"}:
54
+ return (data.high + data.low + data.close + data.close) / 4.0
55
+ if price_mode in {"price_trendfollow1", "trendfollow1"}:
56
+ return (data.high + data.low + data.open + data.close + data.close) / 5.0
57
+ return data.close
58
+
59
+
60
+ class MARoundingChannelIndicator(Indicator):
61
+ """Indicator that derives rounded moving-average centerline and channel bounds."""
62
+
63
+ lines = (
64
+ "base",
65
+ "upper",
66
+ "lower",
67
+ )
68
+ params = (
69
+ ("xma_method", "sma"),
70
+ ("xlength", 12),
71
+ ("xphase", 15),
72
+ ("ipc", "price_close"),
73
+ ("ma_round", 500),
74
+ ("atr_period", 12),
75
+ ("atr_factor", 1.0),
76
+ ("chan_continuity", False),
77
+ )
78
+
79
+ def __init__(self):
80
+ """Resolve MA and ATR dependencies and initialize rolling channel state."""
81
+ ma_cls = resolve_ma_class(self.p.xma_method)
82
+ price_line = resolve_price_line(self.data, self.p.ipc)
83
+ self.ma = ma_cls(price_line, period=self.p.xlength)
84
+ self.atr = ATR(self.data, period=self.p.atr_period)
85
+ self._ma_ro = None
86
+ self._prev_ma = None
87
+ self._prev_dir = 0
88
+ self._prev_range = 0.0
89
+ self._prev_base = None
90
+ self._prev_prev_base = None
91
+ self._prev_upper = 0.0
92
+ self._prev_lower = 0.0
93
+ self.addminperiod(max(self.p.xlength, self.p.atr_period) + 3)
94
+
95
+ def next(self):
96
+ """Update channel base/upper/lower values from latest MA and ATR context."""
97
+ if self._ma_ro is None:
98
+ self._ma_ro = (
99
+ float(self.data.close[0]) * 0.0 + self.data._dataname["close"].iloc[0] * 0.0
100
+ if False
101
+ else None
102
+ )
103
+ ma_ro = float(getattr(self.data, "_compression", 0) or 0)
104
+ if not ma_ro:
105
+ point = 0.01 if abs(float(self.data.close[0])) >= 1 else 0.0001
106
+ ma_ro = point * float(self.p.ma_round)
107
+ mov_ave0 = float(self.ma[0])
108
+ if self._prev_ma is None:
109
+ self._prev_ma = mov_ave0
110
+ res1 = self._prev_base if self._prev_base is not None else mov_ave0
111
+ if (
112
+ mov_ave0 > self._prev_ma + ma_ro
113
+ or mov_ave0 < self._prev_ma - ma_ro
114
+ or mov_ave0 > res1 + ma_ro
115
+ or mov_ave0 < res1 - ma_ro
116
+ or (mov_ave0 > res1 and self._prev_dir == 1)
117
+ or (mov_ave0 < res1 and self._prev_dir == -1)
118
+ ):
119
+ base = mov_ave0
120
+ else:
121
+ base = res1
122
+ direction = 0
123
+ if base < res1:
124
+ direction = -1
125
+ elif base > res1:
126
+ direction = 1
127
+ else:
128
+ direction = self._prev_dir
129
+ upper = 0.0
130
+ lower = 0.0
131
+ range0 = self._prev_range
132
+ if base == res1:
133
+ if self._prev_prev_base is None or res1 != self._prev_prev_base:
134
+ range0 = float(self.atr[0]) * float(self.p.atr_factor)
135
+ upper = base + range0
136
+ lower = base - range0
137
+ elif self.p.chan_continuity:
138
+ upper = self._prev_upper
139
+ lower = self._prev_lower
140
+ self.lines.base[0] = base
141
+ self.lines.upper[0] = upper
142
+ self.lines.lower[0] = lower
143
+ self._prev_dir = direction
144
+ self._prev_ma = mov_ave0
145
+ self._prev_range = range0
146
+ self._prev_prev_base = self._prev_base
147
+ self._prev_base = base
148
+ self._prev_upper = upper
149
+ self._prev_lower = lower
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env python
2
+ """Functional-test indicators migrated to contrib.
3
+
4
+ Generated from a single functional strategy module to preserve file-local
5
+ helper functions and constants without cross-test name collisions.
6
+ """
7
+
8
+ from .. import (
9
+ MACD,
10
+ Indicator,
11
+ )
12
+
13
+ __all__ = [
14
+ "Macd2Indicator",
15
+ ]
16
+
17
+
18
+ class Macd2Indicator(Indicator):
19
+ """MACD-derived indicator carrying cloud and histogram state for MACD-2."""
20
+
21
+ lines = ("cloud_a", "cloud_b", "hist", "color")
22
+ params = (
23
+ ("fast_macd", 12),
24
+ ("slow_macd", 26),
25
+ ("signal_macd", 9),
26
+ )
27
+
28
+ def __init__(self):
29
+ """Create MACD-based cloud and initialize indicator warmup."""
30
+ self.macd = MACD(
31
+ self.data,
32
+ period_me1=int(self.p.fast_macd),
33
+ period_me2=int(self.p.slow_macd),
34
+ period_signal=int(self.p.signal_macd),
35
+ )
36
+ self.addminperiod(
37
+ int(self.p.signal_macd) + max(int(self.p.fast_macd), int(self.p.slow_macd)) + 2
38
+ )
39
+
40
+ def next(self):
41
+ """Populate cloud, histogram, and trend color lines each bar."""
42
+ main = float(self.macd.macd[0])
43
+ signal = float(self.macd.signal[0])
44
+ hist = 3.0 * (main - signal)
45
+ self.lines.cloud_a[0] = main
46
+ self.lines.cloud_b[0] = signal
47
+ self.lines.hist[0] = hist
48
+ color = 2
49
+ if len(self) > 1:
50
+ prev_hist = float(self.lines.hist[-1])
51
+ if hist > 0:
52
+ if hist > prev_hist:
53
+ color = 4
54
+ elif hist < prev_hist:
55
+ color = 3
56
+ elif hist < 0:
57
+ if hist < prev_hist:
58
+ color = 0
59
+ elif hist > prev_hist:
60
+ color = 1
61
+ self.lines.color[0] = color
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env python
2
+ """Functional-test indicators migrated to contrib.
3
+
4
+ Generated from a single functional strategy module to preserve file-local
5
+ helper functions and constants without cross-test name collisions.
6
+ """
7
+
8
+ from .. import (
9
+ MACD,
10
+ Indicator,
11
+ )
12
+
13
+ __all__ = [
14
+ "MacdCandleIndicator",
15
+ ]
16
+
17
+
18
+ class MacdCandleIndicator(Indicator):
19
+ """MACD-based candle indicator returning open/high/low/close values."""
20
+
21
+ lines = ("macd_open", "macd_high", "macd_low", "macd_close", "color")
22
+ params = (
23
+ ("fast_ema_period", 12),
24
+ ("slow_ema_period", 26),
25
+ ("signal_period", 9),
26
+ ("mode", "signal"),
27
+ )
28
+
29
+ def __init__(self):
30
+ """Create MACD lines and register warmup period."""
31
+ self.addminperiod(
32
+ max(int(self.p.fast_ema_period), int(self.p.slow_ema_period))
33
+ + int(self.p.signal_period)
34
+ + 3
35
+ )
36
+ self.macd_open = MACD(
37
+ self.data.open,
38
+ period_me1=int(self.p.fast_ema_period),
39
+ period_me2=int(self.p.slow_ema_period),
40
+ period_signal=int(self.p.signal_period),
41
+ )
42
+ self.macd_high = MACD(
43
+ self.data.high,
44
+ period_me1=int(self.p.fast_ema_period),
45
+ period_me2=int(self.p.slow_ema_period),
46
+ period_signal=int(self.p.signal_period),
47
+ )
48
+ self.macd_low = MACD(
49
+ self.data.low,
50
+ period_me1=int(self.p.fast_ema_period),
51
+ period_me2=int(self.p.slow_ema_period),
52
+ period_signal=int(self.p.signal_period),
53
+ )
54
+ self.macd_close = MACD(
55
+ self.data.close,
56
+ period_me1=int(self.p.fast_ema_period),
57
+ period_me2=int(self.p.slow_ema_period),
58
+ period_signal=int(self.p.signal_period),
59
+ )
60
+
61
+ def _value(self, macd_obj):
62
+ return float(macd_obj.signal[0]) if self.p.mode == "signal" else float(macd_obj.macd[0])
63
+
64
+ def next(self):
65
+ """Populate output candle components and derive color state per bar."""
66
+ open_value = self._value(self.macd_open)
67
+ high_value = self._value(self.macd_high)
68
+ low_value = self._value(self.macd_low)
69
+ close_value = self._value(self.macd_close)
70
+ self.lines.macd_open[0] = open_value
71
+ self.lines.macd_high[0] = high_value
72
+ self.lines.macd_low[0] = low_value
73
+ self.lines.macd_close[0] = close_value
74
+ if open_value < close_value:
75
+ color = 2
76
+ elif open_value > close_value:
77
+ color = 0
78
+ else:
79
+ color = 1
80
+ self.lines.color[0] = color
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env python
2
+ """Functional-test indicators migrated to contrib.
3
+
4
+ Generated from a single functional strategy module to preserve file-local
5
+ helper functions and constants without cross-test name collisions.
6
+ """
7
+
8
+ from .. import (
9
+ Indicator,
10
+ SimpleMovingAverage,
11
+ StandardDeviation,
12
+ WeightedMovingAverage,
13
+ )
14
+
15
+ __all__ = [
16
+ "MalrIndicator",
17
+ ]
18
+
19
+
20
+ class MalrIndicator(Indicator):
21
+ """Compute MALR trend channels used for breakout-trigger detection."""
22
+
23
+ lines = ("malr", "malrh", "malrl", "malrhh", "malrll")
24
+ params = (
25
+ ("ma_period", 120),
26
+ ("ma_shift", 0),
27
+ ("channel_reversal", 1.1),
28
+ ("channel_breakout", 1.1),
29
+ )
30
+
31
+ def __init__(self):
32
+ """Initialize MA basis and channel deviation buffers."""
33
+ sma = SimpleMovingAverage(self.data.close, period=self.p.ma_period)
34
+ lwma = WeightedMovingAverage(self.data.close, period=self.p.ma_period)
35
+ self._ff = 3.0 * lwma - 2.0 * sma
36
+ diff = self.data.close - self._ff
37
+ self._std = StandardDeviation(diff, period=self.p.ma_period)
38
+ self.addminperiod(int(self.p.ma_period) * 2 + 3)
39
+
40
+ def next(self):
41
+ """Calculate MALR center and channel boundaries for the current bar."""
42
+ ff = float(self._ff[0])
43
+ std = float(self._std[0])
44
+ t1 = std * float(self.p.channel_reversal)
45
+ t2 = std * (float(self.p.channel_reversal) + float(self.p.channel_breakout))
46
+ self.lines.malr[0] = ff
47
+ self.lines.malrh[0] = ff + t1
48
+ self.lines.malrl[0] = ff - t1
49
+ self.lines.malrhh[0] = ff + t2
50
+ self.lines.malrll[0] = ff - t2
51
+
52
+ def once(self, start, end):
53
+ """Vectorized computation path for backtesting efficiency."""
54
+ ff_array = self._ff.array
55
+ std_array = self._std.array
56
+ lines = (
57
+ self.lines.malr.array,
58
+ self.lines.malrh.array,
59
+ self.lines.malrl.array,
60
+ self.lines.malrhh.array,
61
+ self.lines.malrll.array,
62
+ )
63
+ for line in lines:
64
+ while len(line) < end:
65
+ line.append(float("nan"))
66
+
67
+ actual_end = min(end, len(ff_array), len(std_array))
68
+ for i in range(start, actual_end):
69
+ ff = float(ff_array[i])
70
+ std = float(std_array[i])
71
+ t1 = std * float(self.p.channel_reversal)
72
+ t2 = std * (float(self.p.channel_reversal) + float(self.p.channel_breakout))
73
+ lines[0][i] = ff
74
+ lines[1][i] = ff + t1
75
+ lines[2][i] = ff - t1
76
+ lines[3][i] = ff + t2
77
+ lines[4][i] = ff - t2
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env python
2
+ """Functional-test indicators migrated to contrib.
3
+
4
+ Generated from a single functional strategy module to preserve file-local
5
+ helper functions and constants without cross-test name collisions.
6
+ """
7
+
8
+ from .. import (
9
+ ATR,
10
+ Indicator,
11
+ Momentum,
12
+ )
13
+
14
+ __all__ = [
15
+ "MomentumCandleSignIndicator",
16
+ ]
17
+
18
+
19
+ class MomentumCandleSignIndicator(Indicator):
20
+ """Emit ATR-offset buy/sell dots on open/close momentum crossovers."""
21
+
22
+ lines = ("sell_signal", "buy_signal", "momentum_open", "momentum_close")
23
+ params = (
24
+ ("period", 12),
25
+ ("atr_period", 15),
26
+ )
27
+
28
+ def __init__(self):
29
+ """Build open/close momentum and ATR sub-indicators and set min period."""
30
+ self.addminperiod(max(int(self.p.period), int(self.p.atr_period)) + 3)
31
+ self.momentum_open = Momentum(self.data.open, period=int(self.p.period))
32
+ self.momentum_close = Momentum(self.data.close, period=int(self.p.period))
33
+ self.atr = ATR(self.data, period=int(self.p.atr_period))
34
+
35
+ def next(self):
36
+ """Detect momentum crossovers and place ATR-offset signal dots."""
37
+ self.lines.sell_signal[0] = 0.0
38
+ self.lines.buy_signal[0] = 0.0
39
+ self.lines.momentum_open[0] = float(self.momentum_open[0])
40
+ self.lines.momentum_close[0] = float(self.momentum_close[0])
41
+ if len(self.data) < 2:
42
+ return
43
+ prev_open = float(self.momentum_open[-1])
44
+ prev_close = float(self.momentum_close[-1])
45
+ curr_open = float(self.momentum_open[0])
46
+ curr_close = float(self.momentum_close[0])
47
+ atr = float(self.atr[0])
48
+ if prev_open >= prev_close and curr_open < curr_close:
49
+ self.lines.buy_signal[0] = float(self.data.low[0]) - atr * 3.0 / 8.0
50
+ if prev_open <= prev_close and curr_open > curr_close:
51
+ self.lines.sell_signal[0] = float(self.data.high[0]) + atr * 3.0 / 8.0
@@ -0,0 +1,139 @@
1
+ #!/usr/bin/env python
2
+ """Functional-test indicators migrated to contrib.
3
+
4
+ Generated from a single functional strategy module to preserve file-local
5
+ helper functions and constants without cross-test name collisions.
6
+ """
7
+
8
+ import re
9
+ from collections import deque
10
+ from pathlib import Path
11
+
12
+ from .. import Indicator
13
+
14
+ __all__ = [
15
+ "MovingAverageFNIndicator",
16
+ ]
17
+
18
+
19
+ SOURCE_MQ5 = (
20
+ Path(__file__).resolve().parents[2]
21
+ / "ea"
22
+ / "1276_Exp_MovingAverage_FN"
23
+ / "movingaverage_fn.mq5"
24
+ )
25
+
26
+
27
+ def resolve_price_line(data, mode):
28
+ """Return the price line selected by an MT5 applied-price mode.
29
+
30
+ Args:
31
+ data: The data feed providing OHLC lines.
32
+ mode: Applied-price mode name (e.g. ``price_close``, ``price_median``).
33
+
34
+ Returns:
35
+ The line or line expression for the requested applied price; defaults
36
+ to the close line for unrecognized modes.
37
+ """
38
+ price_mode = str(mode).lower()
39
+ if price_mode in {"price_open", "open"}:
40
+ return data.open
41
+ if price_mode in {"price_high", "high"}:
42
+ return data.high
43
+ if price_mode in {"price_low", "low"}:
44
+ return data.low
45
+ if price_mode in {"price_median", "median"}:
46
+ return (data.high + data.low) / 2.0
47
+ if price_mode in {"price_typical", "typical"}:
48
+ return (data.high + data.low + data.close) / 3.0
49
+ if price_mode in {"price_weighted", "weighted"}:
50
+ return (data.high + data.low + data.close + data.close) / 4.0
51
+ return data.close
52
+
53
+
54
+ def load_fn_coefficients(filter_name="N44"):
55
+ """Parse FIR filter coefficients for a named filter from the MQ5 source.
56
+
57
+ Args:
58
+ filter_name: Filter case name (e.g. ``N44``) to extract.
59
+
60
+ Returns:
61
+ List of float coefficients ordered by price-series offset; ``[1.0]`` if
62
+ the source file is missing.
63
+
64
+ Raises:
65
+ ValueError: If the filter or the following case marker is not found.
66
+ """
67
+ if not SOURCE_MQ5.exists():
68
+ return [1.0]
69
+ raw = SOURCE_MQ5.read_bytes()
70
+ candidates = []
71
+ for encoding in ("utf-16", "utf-16-le", "utf-8", "latin-1"):
72
+ candidates.append(raw.decode(encoding, errors="ignore"))
73
+ text = ""
74
+ for candidate in candidates:
75
+ normalized = candidate.replace("\x00", "")
76
+ if f"case {filter_name}:" in normalized:
77
+ text = normalized
78
+ break
79
+ if not text:
80
+ text = raw.decode("latin-1", errors="ignore").replace("\x00", "")
81
+ start = text.find(f"case {filter_name}:")
82
+ if start == -1:
83
+ raise ValueError(f"Filter {filter_name} not found in {SOURCE_MQ5}")
84
+ next_case = re.search(r"\n\s*case\s+N\d+:", text[start + 1 :])
85
+ if not next_case:
86
+ raise ValueError(f"Could not locate next filter after {filter_name}")
87
+ block = text[start : start + 1 + next_case.start()]
88
+ matches = re.findall(
89
+ r"([+-]?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)\*PriceSeries\(Price,index(?:-(\d+))?", block
90
+ )
91
+ coeff_map = {int(offset or "0"): float(coef) for coef, offset in matches}
92
+ coeffs = [coeff_map[i] for i in range(max(coeff_map) + 1)]
93
+ return coeffs
94
+
95
+
96
+ class MovingAverageFNIndicator(Indicator):
97
+ """FIR moving average built from named filter coefficients plus smoothing."""
98
+
99
+ lines = ("mafn",)
100
+ params = (
101
+ ("filter_number", "N44"),
102
+ ("xma_method", "jjma"),
103
+ ("xlength", 12),
104
+ ("xphase", 15),
105
+ ("ipc", "price_close"),
106
+ ("price_shift", 0),
107
+ )
108
+
109
+ def __init__(self):
110
+ """Load the filter coefficients and set up the smoothing buffer."""
111
+ self._coeffs = load_fn_coefficients(self.p.filter_number)
112
+ self._price_line = resolve_price_line(self.data, self.p.ipc)
113
+ self._smooth_values = deque(maxlen=max(1, int(self.p.xlength)))
114
+ self.addminperiod(len(self._coeffs) + self.p.xlength + 5)
115
+
116
+ def _smooth_filtered(self, value):
117
+ self._smooth_values.append(value)
118
+ values = list(self._smooth_values)
119
+ if not values:
120
+ return value
121
+ mode = str(self.p.xma_method).lower()
122
+ if mode in {"sma", "mode_sma"}:
123
+ return sum(values) / len(values)
124
+ if mode in {"ema", "mode_ema"}:
125
+ alpha = 2.0 / (len(values) + 1.0)
126
+ ema = values[0]
127
+ for item in values[1:]:
128
+ ema = alpha * item + (1.0 - alpha) * ema
129
+ return ema
130
+ weights = list(range(1, len(values) + 1))
131
+ weight_sum = float(sum(weights))
132
+ return sum(v * w for v, w in zip(values, weights)) / weight_sum
133
+
134
+ def next(self):
135
+ """Convolve the filter coefficients with price and emit the smoothed value."""
136
+ filtered = 0.0
137
+ for offset, coef in enumerate(self._coeffs):
138
+ filtered += coef * float(self._price_line[-offset])
139
+ self.lines.mafn[0] = self._smooth_filtered(filtered) + float(self.p.price_shift)