test_financial.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. from __future__ import division, absolute_import, print_function
  2. from decimal import Decimal
  3. import numpy as np
  4. from numpy.testing import (
  5. assert_, assert_almost_equal, assert_allclose, assert_equal, assert_raises
  6. )
  7. class TestFinancial(object):
  8. def test_rate(self):
  9. assert_almost_equal(
  10. np.rate(10, 0, -3500, 10000),
  11. 0.1107, 4)
  12. def test_rate_decimal(self):
  13. rate = np.rate(Decimal('10'), Decimal('0'), Decimal('-3500'), Decimal('10000'))
  14. assert_equal(Decimal('0.1106908537142689284704528100'), rate)
  15. def test_irr(self):
  16. v = [-150000, 15000, 25000, 35000, 45000, 60000]
  17. assert_almost_equal(np.irr(v), 0.0524, 2)
  18. v = [-100, 0, 0, 74]
  19. assert_almost_equal(np.irr(v), -0.0955, 2)
  20. v = [-100, 39, 59, 55, 20]
  21. assert_almost_equal(np.irr(v), 0.28095, 2)
  22. v = [-100, 100, 0, -7]
  23. assert_almost_equal(np.irr(v), -0.0833, 2)
  24. v = [-100, 100, 0, 7]
  25. assert_almost_equal(np.irr(v), 0.06206, 2)
  26. v = [-5, 10.5, 1, -8, 1]
  27. assert_almost_equal(np.irr(v), 0.0886, 2)
  28. # Test that if there is no solution then np.irr returns nan
  29. # Fixes gh-6744
  30. v = [-1, -2, -3]
  31. assert_equal(np.irr(v), np.nan)
  32. def test_pv(self):
  33. assert_almost_equal(np.pv(0.07, 20, 12000, 0), -127128.17, 2)
  34. def test_pv_decimal(self):
  35. assert_equal(np.pv(Decimal('0.07'), Decimal('20'), Decimal('12000'), Decimal('0')),
  36. Decimal('-127128.1709461939327295222005'))
  37. def test_fv(self):
  38. assert_equal(np.fv(0.075, 20, -2000, 0, 0), 86609.362673042924)
  39. def test_fv_decimal(self):
  40. assert_equal(np.fv(Decimal('0.075'), Decimal('20'), Decimal('-2000'), 0, 0),
  41. Decimal('86609.36267304300040536731624'))
  42. def test_pmt(self):
  43. res = np.pmt(0.08 / 12, 5 * 12, 15000)
  44. tgt = -304.145914
  45. assert_allclose(res, tgt)
  46. # Test the edge case where rate == 0.0
  47. res = np.pmt(0.0, 5 * 12, 15000)
  48. tgt = -250.0
  49. assert_allclose(res, tgt)
  50. # Test the case where we use broadcast and
  51. # the arguments passed in are arrays.
  52. res = np.pmt([[0.0, 0.8], [0.3, 0.8]], [12, 3], [2000, 20000])
  53. tgt = np.array([[-166.66667, -19311.258], [-626.90814, -19311.258]])
  54. assert_allclose(res, tgt)
  55. def test_pmt_decimal(self):
  56. res = np.pmt(Decimal('0.08') / Decimal('12'), 5 * 12, 15000)
  57. tgt = Decimal('-304.1459143262052370338701494')
  58. assert_equal(res, tgt)
  59. # Test the edge case where rate == 0.0
  60. res = np.pmt(Decimal('0'), Decimal('60'), Decimal('15000'))
  61. tgt = -250
  62. assert_equal(res, tgt)
  63. # Test the case where we use broadcast and
  64. # the arguments passed in are arrays.
  65. res = np.pmt([[Decimal('0'), Decimal('0.8')], [Decimal('0.3'), Decimal('0.8')]],
  66. [Decimal('12'), Decimal('3')], [Decimal('2000'), Decimal('20000')])
  67. tgt = np.array([[Decimal('-166.6666666666666666666666667'), Decimal('-19311.25827814569536423841060')],
  68. [Decimal('-626.9081401700757748402586600'), Decimal('-19311.25827814569536423841060')]])
  69. # Cannot use the `assert_allclose` because it uses isfinite under the covers
  70. # which does not support the Decimal type
  71. # See issue: https://github.com/numpy/numpy/issues/9954
  72. assert_equal(res[0][0], tgt[0][0])
  73. assert_equal(res[0][1], tgt[0][1])
  74. assert_equal(res[1][0], tgt[1][0])
  75. assert_equal(res[1][1], tgt[1][1])
  76. def test_ppmt(self):
  77. assert_equal(np.round(np.ppmt(0.1 / 12, 1, 60, 55000), 2), -710.25)
  78. def test_ppmt_decimal(self):
  79. assert_equal(np.ppmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('60'), Decimal('55000')),
  80. Decimal('-710.2541257864217612489830917'))
  81. # Two tests showing how Decimal is actually getting at a more exact result
  82. # .23 / 12 does not come out nicely as a float but does as a decimal
  83. def test_ppmt_special_rate(self):
  84. assert_equal(np.round(np.ppmt(0.23 / 12, 1, 60, 10000000000), 8), -90238044.232277036)
  85. def test_ppmt_special_rate_decimal(self):
  86. # When rounded out to 8 decimal places like the float based test, this should not equal the same value
  87. # as the float, substituted for the decimal
  88. def raise_error_because_not_equal():
  89. assert_equal(
  90. round(np.ppmt(Decimal('0.23') / Decimal('12'), 1, 60, Decimal('10000000000')), 8),
  91. Decimal('-90238044.232277036'))
  92. assert_raises(AssertionError, raise_error_because_not_equal)
  93. assert_equal(np.ppmt(Decimal('0.23') / Decimal('12'), 1, 60, Decimal('10000000000')),
  94. Decimal('-90238044.2322778884413969909'))
  95. def test_ipmt(self):
  96. assert_almost_equal(np.round(np.ipmt(0.1 / 12, 1, 24, 2000), 2), -16.67)
  97. def test_ipmt_decimal(self):
  98. result = np.ipmt(Decimal('0.1') / Decimal('12'), 1, 24, 2000)
  99. assert_equal(result.flat[0], Decimal('-16.66666666666666666666666667'))
  100. def test_nper(self):
  101. assert_almost_equal(np.nper(0.075, -2000, 0, 100000.),
  102. 21.54, 2)
  103. def test_nper2(self):
  104. assert_almost_equal(np.nper(0.0, -2000, 0, 100000.),
  105. 50.0, 1)
  106. def test_npv(self):
  107. assert_almost_equal(
  108. np.npv(0.05, [-15000, 1500, 2500, 3500, 4500, 6000]),
  109. 122.89, 2)
  110. def test_npv_decimal(self):
  111. assert_equal(
  112. np.npv(Decimal('0.05'), [-15000, 1500, 2500, 3500, 4500, 6000]),
  113. Decimal('122.894854950942692161628715'))
  114. def test_mirr(self):
  115. val = [-4500, -800, 800, 800, 600, 600, 800, 800, 700, 3000]
  116. assert_almost_equal(np.mirr(val, 0.08, 0.055), 0.0666, 4)
  117. val = [-120000, 39000, 30000, 21000, 37000, 46000]
  118. assert_almost_equal(np.mirr(val, 0.10, 0.12), 0.126094, 6)
  119. val = [100, 200, -50, 300, -200]
  120. assert_almost_equal(np.mirr(val, 0.05, 0.06), 0.3428, 4)
  121. val = [39000, 30000, 21000, 37000, 46000]
  122. assert_(np.isnan(np.mirr(val, 0.10, 0.12)))
  123. def test_mirr_decimal(self):
  124. val = [Decimal('-4500'), Decimal('-800'), Decimal('800'), Decimal('800'),
  125. Decimal('600'), Decimal('600'), Decimal('800'), Decimal('800'),
  126. Decimal('700'), Decimal('3000')]
  127. assert_equal(np.mirr(val, Decimal('0.08'), Decimal('0.055')),
  128. Decimal('0.066597175031553548874239618'))
  129. val = [Decimal('-120000'), Decimal('39000'), Decimal('30000'),
  130. Decimal('21000'), Decimal('37000'), Decimal('46000')]
  131. assert_equal(np.mirr(val, Decimal('0.10'), Decimal('0.12')), Decimal('0.126094130365905145828421880'))
  132. val = [Decimal('100'), Decimal('200'), Decimal('-50'),
  133. Decimal('300'), Decimal('-200')]
  134. assert_equal(np.mirr(val, Decimal('0.05'), Decimal('0.06')), Decimal('0.342823387842176663647819868'))
  135. val = [Decimal('39000'), Decimal('30000'), Decimal('21000'), Decimal('37000'), Decimal('46000')]
  136. assert_(np.isnan(np.mirr(val, Decimal('0.10'), Decimal('0.12'))))
  137. def test_when(self):
  138. # begin
  139. assert_equal(np.rate(10, 20, -3500, 10000, 1),
  140. np.rate(10, 20, -3500, 10000, 'begin'))
  141. # end
  142. assert_equal(np.rate(10, 20, -3500, 10000),
  143. np.rate(10, 20, -3500, 10000, 'end'))
  144. assert_equal(np.rate(10, 20, -3500, 10000, 0),
  145. np.rate(10, 20, -3500, 10000, 'end'))
  146. # begin
  147. assert_equal(np.pv(0.07, 20, 12000, 0, 1),
  148. np.pv(0.07, 20, 12000, 0, 'begin'))
  149. # end
  150. assert_equal(np.pv(0.07, 20, 12000, 0),
  151. np.pv(0.07, 20, 12000, 0, 'end'))
  152. assert_equal(np.pv(0.07, 20, 12000, 0, 0),
  153. np.pv(0.07, 20, 12000, 0, 'end'))
  154. # begin
  155. assert_equal(np.fv(0.075, 20, -2000, 0, 1),
  156. np.fv(0.075, 20, -2000, 0, 'begin'))
  157. # end
  158. assert_equal(np.fv(0.075, 20, -2000, 0),
  159. np.fv(0.075, 20, -2000, 0, 'end'))
  160. assert_equal(np.fv(0.075, 20, -2000, 0, 0),
  161. np.fv(0.075, 20, -2000, 0, 'end'))
  162. # begin
  163. assert_equal(np.pmt(0.08 / 12, 5 * 12, 15000., 0, 1),
  164. np.pmt(0.08 / 12, 5 * 12, 15000., 0, 'begin'))
  165. # end
  166. assert_equal(np.pmt(0.08 / 12, 5 * 12, 15000., 0),
  167. np.pmt(0.08 / 12, 5 * 12, 15000., 0, 'end'))
  168. assert_equal(np.pmt(0.08 / 12, 5 * 12, 15000., 0, 0),
  169. np.pmt(0.08 / 12, 5 * 12, 15000., 0, 'end'))
  170. # begin
  171. assert_equal(np.ppmt(0.1 / 12, 1, 60, 55000, 0, 1),
  172. np.ppmt(0.1 / 12, 1, 60, 55000, 0, 'begin'))
  173. # end
  174. assert_equal(np.ppmt(0.1 / 12, 1, 60, 55000, 0),
  175. np.ppmt(0.1 / 12, 1, 60, 55000, 0, 'end'))
  176. assert_equal(np.ppmt(0.1 / 12, 1, 60, 55000, 0, 0),
  177. np.ppmt(0.1 / 12, 1, 60, 55000, 0, 'end'))
  178. # begin
  179. assert_equal(np.ipmt(0.1 / 12, 1, 24, 2000, 0, 1),
  180. np.ipmt(0.1 / 12, 1, 24, 2000, 0, 'begin'))
  181. # end
  182. assert_equal(np.ipmt(0.1 / 12, 1, 24, 2000, 0),
  183. np.ipmt(0.1 / 12, 1, 24, 2000, 0, 'end'))
  184. assert_equal(np.ipmt(0.1 / 12, 1, 24, 2000, 0, 0),
  185. np.ipmt(0.1 / 12, 1, 24, 2000, 0, 'end'))
  186. # begin
  187. assert_equal(np.nper(0.075, -2000, 0, 100000., 1),
  188. np.nper(0.075, -2000, 0, 100000., 'begin'))
  189. # end
  190. assert_equal(np.nper(0.075, -2000, 0, 100000.),
  191. np.nper(0.075, -2000, 0, 100000., 'end'))
  192. assert_equal(np.nper(0.075, -2000, 0, 100000., 0),
  193. np.nper(0.075, -2000, 0, 100000., 'end'))
  194. def test_decimal_with_when(self):
  195. """Test that decimals are still supported if the when argument is passed"""
  196. # begin
  197. assert_equal(np.rate(Decimal('10'), Decimal('20'), Decimal('-3500'), Decimal('10000'), Decimal('1')),
  198. np.rate(Decimal('10'), Decimal('20'), Decimal('-3500'), Decimal('10000'), 'begin'))
  199. # end
  200. assert_equal(np.rate(Decimal('10'), Decimal('20'), Decimal('-3500'), Decimal('10000')),
  201. np.rate(Decimal('10'), Decimal('20'), Decimal('-3500'), Decimal('10000'), 'end'))
  202. assert_equal(np.rate(Decimal('10'), Decimal('20'), Decimal('-3500'), Decimal('10000'), Decimal('0')),
  203. np.rate(Decimal('10'), Decimal('20'), Decimal('-3500'), Decimal('10000'), 'end'))
  204. # begin
  205. assert_equal(np.pv(Decimal('0.07'), Decimal('20'), Decimal('12000'), Decimal('0'), Decimal('1')),
  206. np.pv(Decimal('0.07'), Decimal('20'), Decimal('12000'), Decimal('0'), 'begin'))
  207. # end
  208. assert_equal(np.pv(Decimal('0.07'), Decimal('20'), Decimal('12000'), Decimal('0')),
  209. np.pv(Decimal('0.07'), Decimal('20'), Decimal('12000'), Decimal('0'), 'end'))
  210. assert_equal(np.pv(Decimal('0.07'), Decimal('20'), Decimal('12000'), Decimal('0'), Decimal('0')),
  211. np.pv(Decimal('0.07'), Decimal('20'), Decimal('12000'), Decimal('0'), 'end'))
  212. # begin
  213. assert_equal(np.fv(Decimal('0.075'), Decimal('20'), Decimal('-2000'), Decimal('0'), Decimal('1')),
  214. np.fv(Decimal('0.075'), Decimal('20'), Decimal('-2000'), Decimal('0'), 'begin'))
  215. # end
  216. assert_equal(np.fv(Decimal('0.075'), Decimal('20'), Decimal('-2000'), Decimal('0')),
  217. np.fv(Decimal('0.075'), Decimal('20'), Decimal('-2000'), Decimal('0'), 'end'))
  218. assert_equal(np.fv(Decimal('0.075'), Decimal('20'), Decimal('-2000'), Decimal('0'), Decimal('0')),
  219. np.fv(Decimal('0.075'), Decimal('20'), Decimal('-2000'), Decimal('0'), 'end'))
  220. # begin
  221. assert_equal(np.pmt(Decimal('0.08') / Decimal('12'), Decimal('5') * Decimal('12'), Decimal('15000.'),
  222. Decimal('0'), Decimal('1')),
  223. np.pmt(Decimal('0.08') / Decimal('12'), Decimal('5') * Decimal('12'), Decimal('15000.'),
  224. Decimal('0'), 'begin'))
  225. # end
  226. assert_equal(np.pmt(Decimal('0.08') / Decimal('12'), Decimal('5') * Decimal('12'), Decimal('15000.'),
  227. Decimal('0')),
  228. np.pmt(Decimal('0.08') / Decimal('12'), Decimal('5') * Decimal('12'), Decimal('15000.'),
  229. Decimal('0'), 'end'))
  230. assert_equal(np.pmt(Decimal('0.08') / Decimal('12'), Decimal('5') * Decimal('12'), Decimal('15000.'),
  231. Decimal('0'), Decimal('0')),
  232. np.pmt(Decimal('0.08') / Decimal('12'), Decimal('5') * Decimal('12'), Decimal('15000.'),
  233. Decimal('0'), 'end'))
  234. # begin
  235. assert_equal(np.ppmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('60'), Decimal('55000'),
  236. Decimal('0'), Decimal('1')),
  237. np.ppmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('60'), Decimal('55000'),
  238. Decimal('0'), 'begin'))
  239. # end
  240. assert_equal(np.ppmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('60'), Decimal('55000'),
  241. Decimal('0')),
  242. np.ppmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('60'), Decimal('55000'),
  243. Decimal('0'), 'end'))
  244. assert_equal(np.ppmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('60'), Decimal('55000'),
  245. Decimal('0'), Decimal('0')),
  246. np.ppmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('60'), Decimal('55000'),
  247. Decimal('0'), 'end'))
  248. # begin
  249. assert_equal(np.ipmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('24'), Decimal('2000'),
  250. Decimal('0'), Decimal('1')).flat[0],
  251. np.ipmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('24'), Decimal('2000'),
  252. Decimal('0'), 'begin').flat[0])
  253. # end
  254. assert_equal(np.ipmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('24'), Decimal('2000'),
  255. Decimal('0')).flat[0],
  256. np.ipmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('24'), Decimal('2000'),
  257. Decimal('0'), 'end').flat[0])
  258. assert_equal(np.ipmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('24'), Decimal('2000'),
  259. Decimal('0'), Decimal('0')).flat[0],
  260. np.ipmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('24'), Decimal('2000'),
  261. Decimal('0'), 'end').flat[0])
  262. def test_broadcast(self):
  263. assert_almost_equal(np.nper(0.075, -2000, 0, 100000., [0, 1]),
  264. [21.5449442, 20.76156441], 4)
  265. assert_almost_equal(np.ipmt(0.1 / 12, list(range(5)), 24, 2000),
  266. [-17.29165168, -16.66666667, -16.03647345,
  267. -15.40102862, -14.76028842], 4)
  268. assert_almost_equal(np.ppmt(0.1 / 12, list(range(5)), 24, 2000),
  269. [-74.998201, -75.62318601, -76.25337923,
  270. -76.88882405, -77.52956425], 4)
  271. assert_almost_equal(np.ppmt(0.1 / 12, list(range(5)), 24, 2000, 0,
  272. [0, 0, 1, 'end', 'begin']),
  273. [-74.998201, -75.62318601, -75.62318601,
  274. -76.88882405, -76.88882405], 4)
  275. def test_broadcast_decimal(self):
  276. # Use almost equal because precision is tested in the explicit tests, this test is to ensure
  277. # broadcast with Decimal is not broken.
  278. assert_almost_equal(np.ipmt(Decimal('0.1') / Decimal('12'), list(range(5)), Decimal('24'), Decimal('2000')),
  279. [Decimal('-17.29165168'), Decimal('-16.66666667'), Decimal('-16.03647345'),
  280. Decimal('-15.40102862'), Decimal('-14.76028842')], 4)
  281. assert_almost_equal(np.ppmt(Decimal('0.1') / Decimal('12'), list(range(5)), Decimal('24'), Decimal('2000')),
  282. [Decimal('-74.998201'), Decimal('-75.62318601'), Decimal('-76.25337923'),
  283. Decimal('-76.88882405'), Decimal('-77.52956425')], 4)
  284. assert_almost_equal(np.ppmt(Decimal('0.1') / Decimal('12'), list(range(5)), Decimal('24'), Decimal('2000'),
  285. Decimal('0'), [Decimal('0'), Decimal('0'), Decimal('1'), 'end', 'begin']),
  286. [Decimal('-74.998201'), Decimal('-75.62318601'), Decimal('-75.62318601'),
  287. Decimal('-76.88882405'), Decimal('-76.88882405')], 4)