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,381 @@
1
+ #!/usr/bin/env python
2
+ """Pandas Data Feed Module - Pandas DataFrame integration.
3
+
4
+ This module provides data feeds for loading market data from
5
+ Pandas DataFrames.
6
+
7
+ Classes:
8
+ PandasDirectData: Uses DataFrame tuples as data source.
9
+ PandasData: Uses DataFrame columns as data source.
10
+
11
+ Example:
12
+ >>> import pandas as pd
13
+ >>> df = pd.read_csv('data.csv')
14
+ >>> data = bt.feeds.PandasData(dataname=df)
15
+ >>> cerebro.adddata(data)
16
+ """
17
+
18
+ from ..feed import DataBase
19
+ from ..utils import date2num
20
+ from ..utils.log_message import get_logger
21
+ from ..utils.py3 import filter, integer_types, string_types
22
+
23
+ logger = get_logger(__name__)
24
+
25
+
26
+ class PandasDirectData(DataBase):
27
+ """
28
+ Uses a Pandas DataFrame as the feed source, iterating directly over the
29
+ tuples returned by "itertuples".
30
+
31
+ This means that all parameters related to lines must have numeric
32
+ values as indices into the tuples
33
+
34
+ Note:
35
+
36
+ - The ``dataname`` parameter is a Pandas DataFrame
37
+
38
+ - A negative value in any of the parameters for the Data lines
39
+ indicates it's not present in the DataFrame
40
+ it is
41
+ """
42
+
43
+ # Parameters
44
+ params = (
45
+ ("datetime", 0),
46
+ ("open", 1),
47
+ ("high", 2),
48
+ ("low", 3),
49
+ ("close", 4),
50
+ ("volume", 5),
51
+ ("openinterest", 6),
52
+ )
53
+ # Column names
54
+ datafields = ["datetime", "open", "high", "low", "close", "volume", "openinterest"]
55
+
56
+ def __init__(self):
57
+ """Initialize the PandasDirect data feed.
58
+
59
+ Prepares for iterating over DataFrame rows.
60
+ """
61
+ super().__init__() # CRITICAL FIX: Must call parent __init__
62
+ self._rows = None
63
+
64
+ def start(self):
65
+ """Start the PandasDirect data feed.
66
+
67
+ Creates iterator from DataFrame.
68
+ """
69
+ super().start()
70
+
71
+ # reset the iterator on each start
72
+ self._rows = self.p.dataname.itertuples()
73
+
74
+ def _load(self):
75
+ # Try to get next row, return False if error
76
+ try:
77
+ row = next(self._rows)
78
+ except StopIteration:
79
+ return False
80
+
81
+ # Set the standard datafields - except for datetime
82
+ # For columns other than datetime, add data to lines based on column names
83
+ for datafield in self.getlinealiases():
84
+ if datafield == "datetime":
85
+ continue
86
+
87
+ # get the column index
88
+ colidx = getattr(self.params, datafield)
89
+
90
+ if colidx < 0:
91
+ # column is not present -- skip
92
+ continue
93
+
94
+ # get the line to be set
95
+ line = getattr(self.lines, datafield)
96
+ # indexing for pandas: 1st is colum, then row
97
+ line[0] = row[colidx]
98
+
99
+ # datetime
100
+ # For datetime, get the index of datetime column, then get time
101
+ colidx = getattr(self.params, "datetime")
102
+ tstamp = row[colidx]
103
+
104
+ # convert to float via datetime and store it
105
+ # Convert timestamp to specific datetime format, then convert to number
106
+ dt = tstamp.to_pydatetime()
107
+ dtnum = date2num(dt)
108
+
109
+ # get the line to be set
110
+ # Get datetime line, then save this number
111
+ line = getattr(self.lines, "datetime")
112
+ line[0] = dtnum
113
+
114
+ # Done ... return
115
+ return True
116
+
117
+
118
+ class PandasData(DataBase):
119
+ """
120
+ Uses a Pandas DataFrame as the feed source, using indices into column
121
+ names (which can be "numeric")
122
+
123
+ This means that all parameters related to lines must have numeric
124
+ values as indices into the tuples
125
+
126
+ Params:
127
+
128
+ - ``nocase`` (default *True*) case-insensitive match of column names
129
+
130
+ Note:
131
+
132
+ - The ``dataname`` parameter is a Pandas DataFrame
133
+
134
+ - Values possible for datetime
135
+
136
+ - None: the index contains the datetime
137
+ - -1: no index, autodetect column
138
+ - >= 0 or string: specific colum identifier
139
+
140
+ - For other lines parameters
141
+
142
+ - None: column not present
143
+ - -1: autodetect
144
+ - >= 0 or string: specific colum identifier
145
+ """
146
+
147
+ # Parameters and their meanings
148
+ params = (
149
+ ("nocase", True),
150
+ # Possible values for datetime (must always be present)
151
+ # None: datetime is the "index" in the Pandas Dataframe
152
+ # -1: autodetect position or case-wise equal name
153
+ # >= 0: numeric index to the colum in the pandas dataframe
154
+ # string: column name (as index) in the pandas dataframe
155
+ ("datetime", None),
156
+ # The possible values below:
157
+ # None : column not present
158
+ # -1: autodetect position or case-wise equal name
159
+ # >= 0: numeric index to the colum in the pandas dataframe
160
+ # string: column name (as index) in the pandas dataframe
161
+ ("open", -1),
162
+ ("high", -1),
163
+ ("low", -1),
164
+ ("close", -1),
165
+ ("volume", -1),
166
+ ("openinterest", -1),
167
+ )
168
+ # Column names of data
169
+ datafields = ["datetime", "open", "high", "low", "close", "volume", "openinterest"]
170
+
171
+ def __init__(self):
172
+ """Initialize the Pandas data feed.
173
+
174
+ Creates column mappings for DataFrame data access.
175
+ """
176
+ super().__init__()
177
+
178
+ # these "colnames" can be strings or numeric types
179
+ # Column names, list format
180
+ self._idx = None
181
+ self._df_len = 0
182
+ self._loaditems = None
183
+ self._df_values = None
184
+ self._dt_dtnum = None
185
+ self._coldtime = None
186
+ colnames = list(self.p.dataname.columns.values)
187
+ # If datetime is in index
188
+ if self.p.datetime is None:
189
+ # datetime is expected as index col and hence not returned
190
+ pass
191
+
192
+ # try to autodetect if all columns are numeric
193
+ # Try to determine if cstrings are strings, filter out non-strings
194
+ cstrings = filter(lambda x: isinstance(x, string_types), colnames)
195
+ # If there is a string, colsnumeric is False, only returns True when all are numbers
196
+ colsnumeric = not len(list(cstrings))
197
+ if colsnumeric:
198
+ # If all column names are numbers, this flag is True, keep behavior unchanged here
199
+ pass
200
+
201
+ # Where each datafield find its value
202
+ # Define a dictionary
203
+ self._colmapping = {}
204
+
205
+ # Build the column mappings to internal fields in advance
206
+ # Iterate through each column
207
+ for datafield in self.getlinealiases():
208
+ # Index where column is located
209
+ defmapping = getattr(self.params, datafield)
210
+ # If column index is number and less than 0, need auto-detection
211
+ if isinstance(defmapping, integer_types) and defmapping < 0:
212
+ # autodetection requested
213
+ for colname in colnames:
214
+ # If column name is string
215
+ if isinstance(colname, string_types):
216
+ # If case-insensitive, compare lowercase equality, if equal means found,
217
+ # otherwise directly compare if equal
218
+ if self.p.nocase:
219
+ found = datafield.lower() == colname.lower()
220
+ else:
221
+ found = datafield == colname
222
+ # If found, map datafield to colname one-to-one, then exit this loop, continue with datafield
223
+ if found:
224
+ self._colmapping[datafield] = colname
225
+ break
226
+ # If searched through df columns and not found, set to None
227
+ if datafield not in self._colmapping:
228
+ # autodetection requested and not found
229
+ self._colmapping[datafield] = None
230
+ continue
231
+
232
+ # If user defined datafield themselves, directly use user's definition
233
+ else:
234
+ # all other cases -- used given index
235
+ self._colmapping[datafield] = defmapping
236
+
237
+ def _resolve_colmapping(self):
238
+ """Resolve textual column names in self._colmapping to integer indices.
239
+
240
+ Extracted from start(). Honors the ``nocase`` param; a missing column
241
+ falls back to None only when the param default is a negative int,
242
+ otherwise the original ValueError is propagated.
243
+ """
244
+ # Transform names (valid for .ix) into indices (good for .iloc)
245
+ # If case-insensitive, convert column names to lowercase, if sensitive, keep original
246
+ if self.p.nocase:
247
+ colnames = [x.lower() for x in self.p.dataname.columns.values]
248
+ else:
249
+ colnames = list(self.p.dataname.columns.values)
250
+
251
+ # Iterate through datafield and column names
252
+ for k, v in self._colmapping.items():
253
+ # If column name is None, represents this column is likely datetime
254
+ if v is None:
255
+ continue # special marker for datetime
256
+ # If column name is string, if case-insensitive, convert to lowercase first,
257
+ # if sensitive, ignore, then get column index based on column name
258
+ if isinstance(v, string_types):
259
+ try:
260
+ if self.p.nocase:
261
+ v = colnames.index(v.lower())
262
+ else:
263
+ v = colnames.index(v)
264
+ except ValueError as e:
265
+ defmap = getattr(self.params, k)
266
+ if isinstance(defmap, integer_types) and defmap < 0:
267
+ v = None
268
+ else:
269
+ raise e # let user now something failed
270
+ # If not string, user defined specific integer, directly use user's definition
271
+ self._colmapping[k] = v
272
+
273
+ def start(self):
274
+ """Start the Pandas data feed.
275
+
276
+ Resets index and converts column names to indices.
277
+ """
278
+ super().start()
279
+ # Before starting, reset _idx first
280
+ # reset the length with each start
281
+ self._idx = -1
282
+
283
+ # Resolve textual column names in the colmapping into integer indices
284
+ self._resolve_colmapping()
285
+
286
+ df = self.p.dataname
287
+ self._df_len = len(df)
288
+
289
+ linealiases = self.getlinealiases()
290
+ loaditems = []
291
+ for datafield in linealiases:
292
+ if datafield == "datetime":
293
+ continue
294
+ colindex = self._colmapping.get(datafield)
295
+ if colindex is None:
296
+ continue
297
+ loaditems.append((getattr(self.lines, datafield), colindex))
298
+
299
+ self._loaditems = loaditems
300
+ self._coldtime = self._colmapping.get("datetime")
301
+
302
+ self._df_values = None
303
+ try:
304
+ self._df_values = df.to_numpy(copy=False)
305
+ except Exception as e:
306
+ logger.warning("Failed to convert DataFrame to numpy array: %s", e)
307
+ self._df_values = None
308
+
309
+ self._dt_dtnum = None
310
+ try:
311
+ coldtime = self._coldtime
312
+ ts = df.index if coldtime is None else df.iloc[:, coldtime]
313
+ try:
314
+ import numpy as np
315
+
316
+ py_dts = np.array(ts.to_pydatetime())
317
+ except Exception as e1:
318
+ logger.debug("ts.to_pydatetime() failed, trying .dt accessor: %s", e1)
319
+ try:
320
+ import warnings
321
+
322
+ import numpy as np
323
+
324
+ with warnings.catch_warnings():
325
+ warnings.simplefilter("ignore", FutureWarning)
326
+ py_dts = np.array(ts.dt.to_pydatetime())
327
+ except Exception as e2:
328
+ logger.debug(
329
+ "ts.dt.to_pydatetime() failed, falling back to element-wise: %s", e2
330
+ )
331
+ py_dts = [x.to_pydatetime() if hasattr(x, "to_pydatetime") else x for x in ts]
332
+ self._dt_dtnum = [date2num(d) for d in py_dts]
333
+ except Exception as e:
334
+ logger.warning("Failed to pre-compute datetime numbers: %s", e)
335
+ self._dt_dtnum = None
336
+
337
+ def _load(self):
338
+ # Load one row at a time, _idx increments by 1 each time
339
+ self._idx += 1
340
+ # If _idx exceeds data length, return False
341
+ if self._idx >= self._df_len:
342
+ # exhausted all rows
343
+ return False
344
+
345
+ row = self._idx
346
+ values = self._df_values
347
+ loaditems = self._loaditems
348
+ dt_dtnum = self._dt_dtnum
349
+ if values is not None and loaditems is not None and dt_dtnum is not None:
350
+ for line, col in loaditems:
351
+ line[0] = values[row, col]
352
+
353
+ self.lines.datetime[0] = dt_dtnum[row]
354
+ return True
355
+
356
+ df = self.p.dataname
357
+ if loaditems is None:
358
+ for datafield in self.getlinealiases():
359
+ if datafield == "datetime":
360
+ continue
361
+
362
+ colindex = self._colmapping[datafield]
363
+ if colindex is None:
364
+ continue
365
+
366
+ line = getattr(self.lines, datafield)
367
+ line[0] = df.iloc[row, colindex]
368
+ else:
369
+ for line, col in loaditems:
370
+ line[0] = df.iloc[row, col]
371
+
372
+ coldtime = self._coldtime
373
+ if coldtime is None:
374
+ tstamp = df.index[row]
375
+ else:
376
+ tstamp = df.iloc[row, coldtime]
377
+
378
+ dt = tstamp.to_pydatetime() if hasattr(tstamp, "to_pydatetime") else tstamp
379
+ self.lines.datetime[0] = date2num(dt)
380
+
381
+ return True
@@ -0,0 +1,256 @@
1
+ #!/usr/bin/env python
2
+ """Quandl Data Feed Module - Quandl data parsing.
3
+
4
+ .. deprecated::
5
+ Quandl was acquired by Nasdaq and the free API has been sunset.
6
+ Use Nasdaq Data Link or alternative data sources instead.
7
+ This module is retained for backward compatibility but will be
8
+ removed in a future release.
9
+
10
+ Classes:
11
+ QuandlCSV: Parses pre-downloaded Quandl CSV files.
12
+ Quandl: Live Quandl data feed.
13
+
14
+ Example:
15
+ >>> data = bt.feeds.QuandlCSV(dataname='quandl.csv')
16
+ >>> cerebro.adddata(data)
17
+ """
18
+
19
+ import collections
20
+ import warnings
21
+
22
+ warnings.warn(
23
+ "backtrader.feeds.quandl is deprecated (Quandl free API sunset). "
24
+ "Consider using Nasdaq Data Link or alternative data sources.",
25
+ DeprecationWarning,
26
+ stacklevel=2,
27
+ )
28
+ import io # noqa: E402
29
+ import itertools # noqa: E402
30
+ from datetime import date, datetime # noqa: E402
31
+
32
+ from .. import feed # noqa: E402
33
+ from ..utils import date2num # noqa: E402
34
+ from ..utils.py3 import urlquote # noqa: E402
35
+
36
+ __all__ = ["QuandlCSV", "Quandl"]
37
+
38
+
39
+ class QuandlCSV(feed.CSVDataBase):
40
+ """
41
+ Parses pre-downloaded Quandl CSV Data Feeds (or locally generated if they
42
+ comply to the Quandl format)
43
+
44
+ Specific parameters:
45
+
46
+ - ``dataname``: The filename to parse or a file-like object
47
+
48
+ - ``reverse`` (default: ``False``)
49
+
50
+ It is assumed that locally stored files have already been reversed
51
+ during the download process
52
+
53
+ - ``adjclose`` (default: ``True``)
54
+
55
+ Whether to use the dividend/split adjusted close and adjust all
56
+ values according to it.
57
+
58
+ - ``round`` (default: ``False``)
59
+
60
+ Whether to round the values to a specific number of decimals after
61
+ having adjusted the close
62
+
63
+ - ``decimals`` (default: ``2``)
64
+
65
+ Number of decimals to round to
66
+ """
67
+
68
+ _online = False # flag to avoid double reversal
69
+
70
+ params = (
71
+ ("reverse", False),
72
+ ("adjclose", True),
73
+ ("round", False),
74
+ ("decimals", 2),
75
+ )
76
+
77
+ def start(self):
78
+ """Start the Quandl CSV data feed.
79
+
80
+ Reverses data if needed for correct chronological order.
81
+ """
82
+ super().start()
83
+
84
+ if not self.params.reverse:
85
+ return
86
+ if self._online:
87
+ return # revers is True but also online, managed with order = asc
88
+
89
+ # Quandl data can be in reverse order -> reverse
90
+ dq: collections.deque = collections.deque()
91
+ for line in self.f:
92
+ dq.appendleft(line)
93
+
94
+ f = io.StringIO(newline=None)
95
+ f.writelines(dq)
96
+ f.seek(0)
97
+ self.f.close()
98
+ self.f = f
99
+
100
+ def _loadline(self, linetokens):
101
+ i = itertools.count(0)
102
+
103
+ dttxt = linetokens[next(i)] # YYYY-MM-DD
104
+ dt = date(int(dttxt[0:4]), int(dttxt[5:7]), int(dttxt[8:10]))
105
+ dtnum = date2num(datetime.combine(dt, self.p.sessionend))
106
+
107
+ self.lines.datetime[0] = dtnum
108
+ if self.p.adjclose:
109
+ for _ in range(7):
110
+ next(i) # skip ohlcv, ex-dividend, split ratio
111
+
112
+ o = float(linetokens[next(i)])
113
+ h = float(linetokens[next(i)])
114
+ low = float(linetokens[next(i)])
115
+ c = float(linetokens[next(i)])
116
+ v = float(linetokens[next(i)])
117
+ self.lines.openinterest[0] = 0.0
118
+
119
+ if self.p.round:
120
+ decimals = self.p.decimals
121
+ o = round(o, decimals)
122
+ h = round(h, decimals)
123
+ low = round(low, decimals)
124
+ c = round(c, decimals)
125
+ v = round(v, decimals)
126
+
127
+ self.lines.open[0] = o
128
+ self.lines.high[0] = h
129
+ self.lines.low[0] = low
130
+ self.lines.close[0] = c
131
+ self.lines.volume[0] = v
132
+
133
+ return True
134
+
135
+
136
+ class Quandl(QuandlCSV):
137
+ """
138
+ Executes a direct download of data from Quandl servers for the given time
139
+ range.
140
+
141
+ Specific parameters (or specific meaning):
142
+
143
+ - ``dataname``
144
+
145
+ The ticker to download ('YHOO', for example)
146
+
147
+ - ``baseurl``
148
+
149
+ The server url. Someone might decide to open a Quandl compatible
150
+ service in the future.
151
+
152
+ - ``proxies``
153
+
154
+ A dict indicating which proxy to go through for the download as in
155
+ {'http': 'http://myproxy.com'} or {'http': 'http://127.0.0.1:8080'}
156
+
157
+ - ``buffered``
158
+
159
+ If True, the entire socket connection will be buffered locally before
160
+ parsing starts.
161
+
162
+ - ``reverse``
163
+
164
+ Quandl returns the value in descending order (newest first). If this is
165
+ ``True`` (the default), the request will tell Quandl to return in
166
+ ascending (oldest to newest) format
167
+
168
+ - ``adjclose``
169
+
170
+ Whether to use the dividend/split adjusted close and adjust all values
171
+ according to it.
172
+
173
+ - ``apikey``
174
+
175
+ Apikey identification in case it may be needed
176
+
177
+ - ``dataset``
178
+
179
+ String identifying the dataset to query. Defaults to ``WIKI``
180
+
181
+ """
182
+
183
+ _online = True # flag to avoid double reversal
184
+
185
+ params: tuple = (
186
+ ("baseurl", "https://www.quandl.com/api/v3/datasets"),
187
+ ("proxies", {}),
188
+ ("buffered", True),
189
+ ("reverse", True),
190
+ ("apikey", None),
191
+ ("dataset", "WIKI"),
192
+ )
193
+
194
+ def __init__(self):
195
+ """Initialize the Quandl data feed.
196
+
197
+ Sets up error tracking for data downloads.
198
+ """
199
+ self.error = None
200
+
201
+ def start(self):
202
+ """Start the Quandl data feed and download data.
203
+
204
+ Constructs URL with parameters and fetches data from Quandl API.
205
+ """
206
+ self.error = None
207
+
208
+ url = f"{self.p.baseurl}/{self.p.dataset}/{urlquote(self.p.dataname)}.csv"
209
+
210
+ urlargs = []
211
+ if self.p.reverse:
212
+ urlargs.append("order=asc")
213
+
214
+ if self.p.apikey is not None:
215
+ urlargs.append(f"api_key={self.p.apikey}")
216
+
217
+ if self.p.fromdate:
218
+ dtxt = self.p.fromdate.strftime("%Y-%m-%d")
219
+ urlargs.append(f"start_date={dtxt}")
220
+
221
+ if self.p.todate:
222
+ dtxt = self.p.todate.strftime("%Y-%m-%d")
223
+ urlargs.append(f"end_date={dtxt}")
224
+
225
+ if urlargs:
226
+ url += "?" + "&".join(urlargs)
227
+
228
+ from ..utils.py3 import ProxyHandler, build_opener, install_opener, urlopen
229
+
230
+ if self.p.proxies:
231
+ proxy = ProxyHandler(self.p.proxies)
232
+ opener = build_opener(proxy)
233
+ install_opener(opener)
234
+
235
+ try:
236
+ datafile = urlopen(url)
237
+ except OSError as e:
238
+ self.error = str(e)
239
+ # leave us empty
240
+ return
241
+
242
+ if datafile.headers["Content-Type"] != "text/csv":
243
+ self.error = "Wrong content type: %s" % datafile.headers
244
+ return # HTML returned? wrong url?
245
+
246
+ if self.params.buffered:
247
+ # buffer everything from the socket into a local buffer
248
+ f = io.StringIO(datafile.read().decode("utf-8"), newline=None)
249
+ datafile.close()
250
+ else:
251
+ f = datafile
252
+
253
+ self.f = f
254
+
255
+ # Prepared a "path" file - CSV Parser can take over
256
+ super().start()