PageRenderTime 29ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/pipeline/test_consensus_estimates.py

https://gitlab.com/lbennett/zipline
Python | 345 lines | 304 code | 29 blank | 12 comment | 5 complexity | 04237ca0383c8b6134383847ed9d71f2 MD5 | raw file
  1. """
  2. Tests for the reference loader for ConsensusEstimates.
  3. """
  4. import blaze as bz
  5. from blaze.compute.core import swap_resources_into_scope
  6. import pandas as pd
  7. from six import iteritems
  8. from zipline.pipeline.common import (
  9. ACTUAL_VALUE_FIELD_NAME,
  10. COUNT_FIELD_NAME,
  11. FISCAL_QUARTER_FIELD_NAME,
  12. FISCAL_YEAR_FIELD_NAME,
  13. HIGH_FIELD_NAME,
  14. LOW_FIELD_NAME,
  15. MEAN_FIELD_NAME,
  16. NEXT_COUNT,
  17. NEXT_FISCAL_QUARTER,
  18. NEXT_FISCAL_YEAR,
  19. NEXT_HIGH,
  20. NEXT_LOW,
  21. NEXT_RELEASE_DATE,
  22. NEXT_STANDARD_DEVIATION,
  23. PREVIOUS_ACTUAL_VALUE,
  24. PREVIOUS_COUNT,
  25. PREVIOUS_FISCAL_QUARTER,
  26. PREVIOUS_FISCAL_YEAR,
  27. PREVIOUS_HIGH,
  28. PREVIOUS_LOW,
  29. PREVIOUS_MEAN, NEXT_MEAN,
  30. PREVIOUS_RELEASE_DATE,
  31. PREVIOUS_STANDARD_DEVIATION,
  32. RELEASE_DATE_FIELD_NAME,
  33. STANDARD_DEVIATION_FIELD_NAME,
  34. SID_FIELD_NAME)
  35. from zipline.pipeline.data import ConsensusEstimates
  36. from zipline.pipeline.loaders.consensus_estimates import (
  37. ConsensusEstimatesLoader
  38. )
  39. from zipline.pipeline.loaders.blaze import BlazeConsensusEstimatesLoader
  40. from zipline.pipeline.loaders.utils import (
  41. zip_with_floats
  42. )
  43. from zipline.testing.fixtures import (
  44. ZiplineTestCase,
  45. WithNextAndPreviousEventDataLoader
  46. )
  47. consensus_estimates_cases = [
  48. # K1--K2--A1--A2.
  49. pd.DataFrame({
  50. ACTUAL_VALUE_FIELD_NAME: (100, 200),
  51. STANDARD_DEVIATION_FIELD_NAME: (.5, .6),
  52. COUNT_FIELD_NAME: (1, 2),
  53. FISCAL_QUARTER_FIELD_NAME: (1, 1),
  54. HIGH_FIELD_NAME: (.6, .7),
  55. MEAN_FIELD_NAME: (.1, .2),
  56. FISCAL_YEAR_FIELD_NAME: (2014, 2014),
  57. LOW_FIELD_NAME: (.05, .06),
  58. }),
  59. # K1--K2--A2--A1.
  60. pd.DataFrame({
  61. ACTUAL_VALUE_FIELD_NAME: (200, 300),
  62. STANDARD_DEVIATION_FIELD_NAME: (.6, .7),
  63. COUNT_FIELD_NAME: (2, 3),
  64. FISCAL_QUARTER_FIELD_NAME: (1, 1),
  65. HIGH_FIELD_NAME: (.7, .8),
  66. MEAN_FIELD_NAME: (.2, .3),
  67. FISCAL_YEAR_FIELD_NAME: (2014, 2014),
  68. LOW_FIELD_NAME: (.06, .07),
  69. }),
  70. # K1--A1--K2--A2.
  71. pd.DataFrame({
  72. ACTUAL_VALUE_FIELD_NAME: (300, 400),
  73. STANDARD_DEVIATION_FIELD_NAME: (.7, .8),
  74. COUNT_FIELD_NAME: (3, 4),
  75. FISCAL_QUARTER_FIELD_NAME: (1, 1),
  76. HIGH_FIELD_NAME: (.8, .9),
  77. MEAN_FIELD_NAME: (.3, .4),
  78. FISCAL_YEAR_FIELD_NAME: (2014, 2014),
  79. LOW_FIELD_NAME: (.07, .08),
  80. }),
  81. # K1 == K2.
  82. pd.DataFrame({
  83. ACTUAL_VALUE_FIELD_NAME: (400, 500),
  84. STANDARD_DEVIATION_FIELD_NAME: (.8, .9),
  85. COUNT_FIELD_NAME: (4, 5),
  86. FISCAL_QUARTER_FIELD_NAME: (1, 1),
  87. HIGH_FIELD_NAME: (.9, 1.0),
  88. MEAN_FIELD_NAME: (.4, .5),
  89. FISCAL_YEAR_FIELD_NAME: (2014, 2014),
  90. LOW_FIELD_NAME: (.08, .09),
  91. }),
  92. pd.DataFrame(
  93. columns=[ACTUAL_VALUE_FIELD_NAME,
  94. STANDARD_DEVIATION_FIELD_NAME,
  95. COUNT_FIELD_NAME,
  96. FISCAL_QUARTER_FIELD_NAME,
  97. HIGH_FIELD_NAME,
  98. MEAN_FIELD_NAME,
  99. FISCAL_YEAR_FIELD_NAME,
  100. LOW_FIELD_NAME],
  101. dtype='datetime64[ns]'
  102. ),
  103. ]
  104. prev_actual_value = [
  105. ['NaN', 100, 200],
  106. ['NaN', 300, 200],
  107. ['NaN', 300, 400],
  108. ['NaN', 400, 500],
  109. ['NaN']
  110. ]
  111. next_standard_deviation = [
  112. ['NaN', .5, .6, 'NaN'],
  113. ['NaN', .6, .7, .6, 'NaN'],
  114. ['NaN', .7, 'NaN', .8, 'NaN'],
  115. ['NaN', .8, .9, 'NaN'],
  116. ['NaN']
  117. ]
  118. prev_standard_deviation = [
  119. ['NaN', .5, .6],
  120. ['NaN', .7, .6],
  121. ['NaN', .7, .8],
  122. ['NaN', .8, .9],
  123. ['NaN']
  124. ]
  125. next_count = [
  126. ['NaN', 1, 2, 'NaN'],
  127. ['NaN', 2, 3, 2, 'NaN'],
  128. ['NaN', 3, 'NaN', 4, 'NaN'],
  129. ['NaN', 4, 5, 'NaN'],
  130. ['NaN']
  131. ]
  132. prev_count = [
  133. ['NaN', 1, 2],
  134. ['NaN', 3, 2],
  135. ['NaN', 3, 4],
  136. ['NaN', 4, 5],
  137. ['NaN']
  138. ]
  139. next_fiscal_quarter = [
  140. ['NaN', 1, 1, 'NaN'],
  141. ['NaN', 1, 1, 1, 'NaN'],
  142. ['NaN', 1, 'NaN', 1, 'NaN'],
  143. ['NaN', 1, 1, 'NaN'],
  144. ['NaN']
  145. ]
  146. prev_fiscal_quarter = [
  147. ['NaN', 1, 1],
  148. ['NaN', 1, 1],
  149. ['NaN', 1, 1],
  150. ['NaN', 1, 1],
  151. ['NaN']
  152. ]
  153. next_high = [
  154. ['NaN', .6, .7, 'NaN'],
  155. ['NaN', .7, .8, .7, 'NaN'],
  156. ['NaN', .8, 'NaN', .9, 'NaN'],
  157. ['NaN', .9, 1.0, 'NaN'],
  158. ['NaN']
  159. ]
  160. prev_high = [
  161. ['NaN', .6, .7],
  162. ['NaN', .8, .7],
  163. ['NaN', .8, .9],
  164. ['NaN', .9, 1.0],
  165. ['NaN']
  166. ]
  167. next_mean = [
  168. ['NaN', .1, .2, 'NaN'],
  169. ['NaN', .2, .3, .2, 'NaN'],
  170. ['NaN', .3, 'NaN', .4, 'NaN'],
  171. ['NaN', .4, .5, 'NaN'],
  172. ['NaN']
  173. ]
  174. prev_mean = [
  175. ['NaN', .1, .2],
  176. ['NaN', .3, .2],
  177. ['NaN', .3, .4],
  178. ['NaN', .4, .5],
  179. ['NaN']
  180. ]
  181. next_fiscal_year = [
  182. ['NaN', 2014, 2014, 'NaN'],
  183. ['NaN', 2014, 2014, 2014, 'NaN'],
  184. ['NaN', 2014, 'NaN', 2014, 'NaN'],
  185. ['NaN', 2014, 2014, 'NaN'],
  186. ['NaN']
  187. ]
  188. prev_fiscal_year = [
  189. ['NaN', 2014, 2014],
  190. ['NaN', 2014, 2014],
  191. ['NaN', 2014, 2014],
  192. ['NaN', 2014, 2014],
  193. ['NaN']
  194. ]
  195. next_low = [
  196. ['NaN', .05, .06, 'NaN'],
  197. ['NaN', .06, .07, .06, 'NaN'],
  198. ['NaN', .07, 'NaN', .08, 'NaN'],
  199. ['NaN', .08, .09, 'NaN'],
  200. ['NaN']
  201. ]
  202. prev_low = [
  203. ['NaN', .05, .06],
  204. ['NaN', .07, .06],
  205. ['NaN', .07, .08],
  206. ['NaN', .08, .09],
  207. ['NaN']
  208. ]
  209. field_name_to_expected_col = {
  210. PREVIOUS_ACTUAL_VALUE: prev_actual_value,
  211. PREVIOUS_STANDARD_DEVIATION: prev_standard_deviation,
  212. NEXT_STANDARD_DEVIATION: next_standard_deviation,
  213. PREVIOUS_COUNT: prev_count,
  214. NEXT_COUNT: next_count,
  215. PREVIOUS_FISCAL_QUARTER: prev_fiscal_quarter,
  216. NEXT_FISCAL_QUARTER: next_fiscal_quarter,
  217. PREVIOUS_HIGH: prev_high,
  218. NEXT_HIGH: next_high,
  219. PREVIOUS_MEAN: prev_mean,
  220. NEXT_MEAN: next_mean,
  221. PREVIOUS_FISCAL_YEAR: prev_fiscal_year,
  222. NEXT_FISCAL_YEAR: next_fiscal_year,
  223. PREVIOUS_LOW: prev_low,
  224. NEXT_LOW: next_low
  225. }
  226. class ConsensusEstimatesLoaderTestCase(WithNextAndPreviousEventDataLoader,
  227. ZiplineTestCase):
  228. """
  229. Tests for loading the consensus estimates data.
  230. """
  231. pipeline_columns = {
  232. PREVIOUS_ACTUAL_VALUE:
  233. ConsensusEstimates.previous_actual_value.latest,
  234. NEXT_RELEASE_DATE:
  235. ConsensusEstimates.next_release_date.latest,
  236. PREVIOUS_RELEASE_DATE:
  237. ConsensusEstimates.previous_release_date.latest,
  238. PREVIOUS_STANDARD_DEVIATION:
  239. ConsensusEstimates.previous_standard_deviation.latest,
  240. NEXT_STANDARD_DEVIATION:
  241. ConsensusEstimates.next_standard_deviation.latest,
  242. PREVIOUS_COUNT:
  243. ConsensusEstimates.previous_count.latest,
  244. NEXT_COUNT:
  245. ConsensusEstimates.next_count.latest,
  246. PREVIOUS_FISCAL_QUARTER:
  247. ConsensusEstimates.previous_fiscal_quarter.latest,
  248. NEXT_FISCAL_QUARTER:
  249. ConsensusEstimates.next_fiscal_quarter.latest,
  250. PREVIOUS_HIGH:
  251. ConsensusEstimates.previous_high.latest,
  252. NEXT_HIGH:
  253. ConsensusEstimates.next_high.latest,
  254. PREVIOUS_MEAN:
  255. ConsensusEstimates.previous_mean.latest,
  256. NEXT_MEAN:
  257. ConsensusEstimates.next_mean.latest,
  258. PREVIOUS_FISCAL_YEAR:
  259. ConsensusEstimates.previous_fiscal_year.latest,
  260. NEXT_FISCAL_YEAR:
  261. ConsensusEstimates.next_fiscal_year.latest,
  262. PREVIOUS_LOW:
  263. ConsensusEstimates.previous_low.latest,
  264. NEXT_LOW:
  265. ConsensusEstimates.next_low.latest
  266. }
  267. @classmethod
  268. def get_dataset(cls):
  269. return {sid:
  270. pd.concat([
  271. cls.base_cases[sid].rename(columns={
  272. 'other_date': RELEASE_DATE_FIELD_NAME
  273. }),
  274. df
  275. ], axis=1)
  276. for sid, df in enumerate(consensus_estimates_cases)}
  277. loader_type = ConsensusEstimatesLoader
  278. def setup(self, dates):
  279. cols = {
  280. PREVIOUS_RELEASE_DATE:
  281. self.get_expected_previous_event_dates(dates),
  282. NEXT_RELEASE_DATE: self.get_expected_next_event_dates(dates)
  283. }
  284. for field_name in field_name_to_expected_col:
  285. cols[field_name] = self.get_sids_to_frames(
  286. zip_with_floats, field_name_to_expected_col[field_name],
  287. self.prev_date_intervals
  288. if field_name.startswith("previous")
  289. else self.next_date_intervals,
  290. dates
  291. )
  292. return cols
  293. class BlazeConsensusEstimatesLoaderTestCase(ConsensusEstimatesLoaderTestCase):
  294. loader_type = BlazeConsensusEstimatesLoader
  295. def pipeline_event_loader_args(self, dates):
  296. _, mapping = super(
  297. BlazeConsensusEstimatesLoaderTestCase,
  298. self,
  299. ).pipeline_event_loader_args(dates)
  300. frames = []
  301. for sid, df in iteritems(mapping):
  302. frame = df.copy()
  303. frame[SID_FIELD_NAME] = sid
  304. frames.append(frame)
  305. return bz.data(pd.concat(frames).reset_index(drop=True)),
  306. class BlazeConsensusEstimatesLoaderNotInteractiveTestCase(
  307. BlazeConsensusEstimatesLoaderTestCase
  308. ):
  309. """Test case for passing a non-interactive symbol and a dict of resources.
  310. """
  311. def pipeline_event_loader_args(self, dates):
  312. (bound_expr,) = super(
  313. BlazeConsensusEstimatesLoaderNotInteractiveTestCase,
  314. self,
  315. ).pipeline_event_loader_args(dates)
  316. return swap_resources_into_scope(bound_expr, {})