Skip to main content

Rust-powered collection of financial functions for Python.

Project description

rust-lang.org License pypi versions

PyXIRR

Rust-powered collection of financial functions for Python.

Features:

  • correct
  • blazingly fast
  • works with iterators
  • works with unordered input
  • no external dependencies

Installation

pip install pyxirr

Benchmarks

Rust implementation has been tested against existing xirr package (uses scipy.optimize under the hood) and the implementation from the Stack Overflow (pure python).

bench

PyXIRR is ~10-20x faster in XIRR calculation. More than 10x faster than numpy-financial.

Powered by github-action-benchmark and plotly.js.

Live benchmarks are hosted on Github Pages.

Examples

from datetime import date
from pyxirr import xirr

dates = [date(2020, 1, 1), date(2021, 1, 1), date(2022, 1, 1)]
amounts = [-1000, 1000, 1000]

# feed columnar data
xirr(dates, amounts)
# feed iterators
xirr(iter(dates), (x for x in amounts))
# feed an iterable of tuples
xirr(zip(dates, amounts))
# feed a dictionary
xirr(dict(zip(dates, amounts)))

Numpy and Pandas support

import numpy as np
import pandas as pd

# feed numpy array
xirr(np.array([dates, amounts]))
xirr(np.array(dates), np.array(amounts))
# feed DataFrame (columns names doesn't matter; ordering matters)
xirr(pd.DataFrame({"a": dates, "b": amounts}))

API reference

Let's define type annotations:

# `None` if the calculation fails to converge or result is NAN.
# could return `inf` or `-inf`
FloatOrNone = Optional[float]

DateLike = Union[datetime.date, datetime.datetime, numpy.datetime64, pandas.Timestamp]
Rate = float  # rate as decimal, not percentage, normally between [-1, 1]
Guess = Optional[Rate]
Amount = Union[int, float, Decimal]
Payment = Tuple[DateLike, Amount]

DateLikeArray = Iterable[DateLike]
AmountArray = Iterable[Amount]
CashFlowTable = Iterable[Payment]
CashFlowDict = Dict[DateLike, Amount]

Exceptions

  • InvalidPaymentsError. Occurs if either:
    • the amounts and dates arrays (AmountArray, DateLikeArray) are of different lengths
    • the given arrays do not contain at least one negative and at least one positive value

XIRR

# raises: InvalidPaymentsError
def xirr(
    dates: Union[CashFlowTable, CashFlowDict, DateLikeArray],
    amounts: Optional[AmountArray] = None,
    guess: Guess = None,
) -> FloatOrNone

XNPV

# raises: InvalidPaymentsError
def xnpv(
    rate: Rate,
    dates: Union[CashFlowTable, CashFlowDict, DateLikeArray],
    amounts: Optional[AmountArray] = None,
) -> FloatOrNone

IRR

Compute the Internal Rate of Return (IRR)

# raises: InvalidPaymentsError
def irr(amounts: AmountArray, guess: Guess = None) -> FloatOrNone

NPV

Compute the Net Present Value.

# raises: InvalidPaymentsError
def npv(rate: Rate, amounts: AmountArray) -> FloatOrNone

FV

Compute the future value.

def fv(
    rate: Rate, # Rate of interest per period
    nper: int, # Number of compounding periods
    pmt: Amount, # Payment
    pv: Amount, # Present value
    pmt_at_begining: bool = False  # When payments are due
) -> FloatOrNone

PV

Compute the present value.

def pv(
    rate: Rate, # Rate of interest per period
    nper: int, # Number of compounding periods
    pmt: Amount, # Payment
    fv: Amount = 0, # Future value
    pmt_at_begining: bool = False  # When payments are due
) -> FloatOrNone

MIRR

Modified internal rate of return.

def mirr(
    values: AmountArray, # Cash flows. Must contain at least one positive and one negative value or nan is returned.
    finance_rate: Rate, # Interest rate paid on the cash flows
    reinvest_rate: Rate, # Interest rate received on the cash flows upon reinvestment
) -> FloatOrNone

Roadmap

  • NumPy support
  • XIRR
  • XNPV
  • NPV
  • IRR
  • FV
  • PV
  • MIRR
  • Improve docs, add more tests
  • other functions from numpy-financial

Development

Running tests with pyo3 is a bit tricky. In short, you need to compile your tests without extension-module feature to avoid linking errors. See the following issues for the details: #341, #771.

If you are using pyenv, make sure you have the shared library installed (check for ${PYENV_ROOT}/versions/<version>/lib/libpython3.so file).

$ PYTHON_CONFIGURE_OPTS="--enable-shared" pyenv install <version>

Install dev-requirements

$ pip install -r dev-requirements.txt

Building

$ maturin develop

Testing

$ LD_LIBRARY_PATH=${PYENV_ROOT}/versions/3.8.6/lib cargo test --no-default-features

Building and distribution

This library uses maturin to build and distribute python wheels.

$ docker run --rm -v $(pwd):/io konstin2/maturin build --release --manylinux 2010 --strip
$ maturin upload target/wheels/pyxirr-${version}*

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyxirr-0.5.1.tar.gz (192.2 kB view details)

Uploaded Source

Built Distributions

pyxirr-0.5.1-cp39-none-win_amd64.whl (122.8 kB view details)

Uploaded CPython 3.9 Windows x86-64

pyxirr-0.5.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl (180.1 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.5+ x86-64

pyxirr-0.5.1-cp39-cp39-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl (339.2 kB view details)

Uploaded CPython 3.9 macOS 10.9+ universal2 (ARM64, x86-64) macOS 10.9+ x86-64 macOS 11.0+ ARM64

pyxirr-0.5.1-cp38-none-win_amd64.whl (122.8 kB view details)

Uploaded CPython 3.8 Windows x86-64

pyxirr-0.5.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl (180.1 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.5+ x86-64

pyxirr-0.5.1-cp38-cp38-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl (339.2 kB view details)

Uploaded CPython 3.8 macOS 10.9+ universal2 (ARM64, x86-64) macOS 10.9+ x86-64 macOS 11.0+ ARM64

pyxirr-0.5.1-cp37-none-win_amd64.whl (122.8 kB view details)

Uploaded CPython 3.7 Windows x86-64

pyxirr-0.5.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl (180.1 kB view details)

Uploaded CPython 3.7m manylinux: glibc 2.5+ x86-64

pyxirr-0.5.1-cp37-cp37m-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl (339.2 kB view details)

Uploaded CPython 3.7m macOS 10.9+ universal2 (ARM64, x86-64) macOS 10.9+ x86-64 macOS 11.0+ ARM64

pyxirr-0.5.1-cp36-none-win_amd64.whl (122.8 kB view details)

Uploaded CPython 3.6 Windows x86-64

pyxirr-0.5.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl (180.1 kB view details)

Uploaded CPython 3.6m manylinux: glibc 2.5+ x86-64

pyxirr-0.5.1-cp36-cp36m-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl (339.4 kB view details)

Uploaded CPython 3.6m macOS 10.9+ universal2 (ARM64, x86-64) macOS 10.9+ x86-64 macOS 11.0+ ARM64

File details

Details for the file pyxirr-0.5.1.tar.gz.

File metadata

  • Download URL: pyxirr-0.5.1.tar.gz
  • Upload date:
  • Size: 192.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/0.10.6

File hashes

Hashes for pyxirr-0.5.1.tar.gz
Algorithm Hash digest
SHA256 e51e834fe16c2e0e6eca8560cd1c6be15bffbe3b95183db3a4ba085f2761ea32
MD5 d2488ad553ef68182324977d1e749c7a
BLAKE2b-256 6d4c84f9a6d11a19c1bfaaf1b085a483fdc60743f085f6bb83d687021cbd06e8

See more details on using hashes here.

File details

Details for the file pyxirr-0.5.1-cp39-none-win_amd64.whl.

File metadata

  • Download URL: pyxirr-0.5.1-cp39-none-win_amd64.whl
  • Upload date:
  • Size: 122.8 kB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/0.10.6

File hashes

Hashes for pyxirr-0.5.1-cp39-none-win_amd64.whl
Algorithm Hash digest
SHA256 11520bcbbf089fc1b5a04f3e5418f15f8b0189d36d7f4db1e59329b30968c700
MD5 300a02ab5f2a03f4a553874d175005d7
BLAKE2b-256 84599a532535c50ce38a1538c6bf5b85f6dfe0bbf85fd51f1ec0d3f5f16d40e8

See more details on using hashes here.

File details

Details for the file pyxirr-0.5.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for pyxirr-0.5.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 0c5c409c94ad01eb7435acb430b7fcb37b6a93e18ee5d0559137aa476eb66f5c
MD5 096e6376ccc3e78191a242b5bb387449
BLAKE2b-256 32312681741ff1b130b9cc57f3e45824697ab69c5f0f1ded3d5b514cdd91feac

See more details on using hashes here.

File details

Details for the file pyxirr-0.5.1-cp39-cp39-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for pyxirr-0.5.1-cp39-cp39-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 63206699c30a26bb72dd49ead8e9b413f0c19753bfa7577a0e84033a152554c0
MD5 5d8026c4c40f176083340f03636dca03
BLAKE2b-256 57d5e9224020a7f60e5308ddd009af05f17661b3ae24f163656759ec39919e40

See more details on using hashes here.

File details

Details for the file pyxirr-0.5.1-cp38-none-win_amd64.whl.

File metadata

  • Download URL: pyxirr-0.5.1-cp38-none-win_amd64.whl
  • Upload date:
  • Size: 122.8 kB
  • Tags: CPython 3.8, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/0.10.6

File hashes

Hashes for pyxirr-0.5.1-cp38-none-win_amd64.whl
Algorithm Hash digest
SHA256 cb1b5252655bd2f0708dc09f72d66fd1c7a190751ce55bdd5271b60bb8ef36a6
MD5 13e3d982c2b6f22c60c2dc6c3d0c653b
BLAKE2b-256 616fece8583d591e7131b19d5b444b2b86b3c5b9a74f9726f33ad115c39aeffe

See more details on using hashes here.

File details

Details for the file pyxirr-0.5.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for pyxirr-0.5.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 586a3cbd16e395c6ed07d538eab49daf35383f368f41e8364b75dfc3a30d9ed6
MD5 c2bf2345d90c860f878277d009a3195a
BLAKE2b-256 7c2c9f00166c4533161e933b714361ca555caa4ad4367fa08aa1604c5be8ba69

See more details on using hashes here.

File details

Details for the file pyxirr-0.5.1-cp38-cp38-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for pyxirr-0.5.1-cp38-cp38-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 cfa084102c1914565164f9e4176e2f1813249abb880fd3726b26bfbec19efad2
MD5 7908be29cfe35f25ecc2cd531bc1ce4b
BLAKE2b-256 078098579b51060f970de59be857a0bff47c0d297ee63804636ea177f33b873b

See more details on using hashes here.

File details

Details for the file pyxirr-0.5.1-cp37-none-win_amd64.whl.

File metadata

  • Download URL: pyxirr-0.5.1-cp37-none-win_amd64.whl
  • Upload date:
  • Size: 122.8 kB
  • Tags: CPython 3.7, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/0.10.6

File hashes

Hashes for pyxirr-0.5.1-cp37-none-win_amd64.whl
Algorithm Hash digest
SHA256 2ff17863065519a9c5948c38add5969621f749fe644ccf1c8f37fd690276e3fd
MD5 ae9ba0db477af20c0a60712d65efeb77
BLAKE2b-256 f385017ce24251e1bd5876f75453e65a66987c00cd972b15920e3fc06586796c

See more details on using hashes here.

File details

Details for the file pyxirr-0.5.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for pyxirr-0.5.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 b2ae044f7a43c50fbcfd31a73a66b0616f3604bb74efe6841016f66c98efa5bf
MD5 238d6c7d85e326e6fce71baa661a2be5
BLAKE2b-256 642043f9dd5a26798ec2b6805739094a7bc33ea91d269068e0b4168c3a6c61dc

See more details on using hashes here.

File details

Details for the file pyxirr-0.5.1-cp37-cp37m-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for pyxirr-0.5.1-cp37-cp37m-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 80c092a0b25338696a619c41e7cfd40d2f6f40b8917cf268df66dd92ea2558c9
MD5 9eb51cd29921d040e5c98d40e6700598
BLAKE2b-256 e1eeca631da311fd6a4c1873da781677e3c2465895bc2a491a7e83b13b633980

See more details on using hashes here.

File details

Details for the file pyxirr-0.5.1-cp36-none-win_amd64.whl.

File metadata

  • Download URL: pyxirr-0.5.1-cp36-none-win_amd64.whl
  • Upload date:
  • Size: 122.8 kB
  • Tags: CPython 3.6, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/0.10.6

File hashes

Hashes for pyxirr-0.5.1-cp36-none-win_amd64.whl
Algorithm Hash digest
SHA256 682c8b806f21e5a96d069508ec62bbdfa6751c883420026d3dc817f64a2d3001
MD5 10904b7d1e2bef81f1b61873f9e1c545
BLAKE2b-256 60ed2a5f6f99d058448d77e29ed38c99c3a026a5e980e08b4715180dde51fcd7

See more details on using hashes here.

File details

Details for the file pyxirr-0.5.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for pyxirr-0.5.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 aef7d03f55b36fcb129b4a34d85570277b1e001521e9efed3b6c83658feb3432
MD5 23536a47848fa120ce75ee819ff59c77
BLAKE2b-256 8e77dd9559cc22f03a35c60ab89f19c86866c35c566b9307cc992259ade3e74d

See more details on using hashes here.

File details

Details for the file pyxirr-0.5.1-cp36-cp36m-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for pyxirr-0.5.1-cp36-cp36m-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 eb85f763105541380f7084700881b8d67425f3d958694b3415d9dba7be3937d8
MD5 7c8e41971dca16924f49cdf92d76293d
BLAKE2b-256 6b21feda5dcaa338bfe97f2209dee9db451cbe1f5905327881b706db533cfc22

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page