Skip to main content

Compute with dated monetary values.

Project description

Dated Money

Dated Money is a Python library for manipulating monetary values with control over the date on which currency conversions take place. It represents each monetary value as an amount (stored as a Decimal in cents) and a currency, along with a corresponding date.

It differs from the money package in that it treats the date as a first-class element.

It downloads and saves today's conversion rates from https://www.exchangerate-api.com/ using your API key (see below). You may need a paid account for the fetching of rates for days other than today to work.

Features

  • Perform arithmetic operations on monetary values with different currencies and dates
  • Convert monetary values between currencies based on exchange rates for specific dates
  • Fetch and cache exchange rates from external APIs or local repositories
  • Flexible configuration through environment variables

Installation

You can install Dated Money using pip:

pip install dated-money

Usage

Basic Examples

from decimal import Decimal as Dec
from dmon import Money, Currency

# Create a Money class with EUR as the base currency and conversion rates from a specific date
date_a = '2022-07-14'
Eur = Money(Currency.EUR, date_a)

# Create a Money class with AUD as the base currency and conversion rates from the same date
Aud = Money(base_currency='A$', base_date=date_a)

# Create monetary values in different currencies
price_eur = Eur(100)  # €100
price_usd = Eur(120, Currency.USD)  # $120
price_gbp = Eur(80, '£')  # £80

# Values are stored in cents and can be accessed in any currency
assert Eur(23, '€').cents('eur') == 2300
assert Eur(40).cents('usd') == Dec('4020.100502512562832012897042')

# Values can be created in any currency, regardless of the base currency
assert Eur(20, '£') == Aud(20, '£')

# Perform arithmetic operations
total = price_eur + price_usd + price_gbp
assert str(total) == '€270.40'  # Total in the base currency (EUR)

# Convert to a specific currency
total_usd = total.to(Currency.USD)
assert str(total_usd) == '$303.89'

# Compare monetary values
assert price_eur < price_usd
assert price_gbp == Eur(80, Currency.GBP)

Operations with Different Currencies and Dates

You can perform operations on monetary values with different currencies and conversion dates:

date_a = '2022-07-14'
date_b = '2022-01-07'

Eur = Money(Currency.EUR, date_a)
OldEur = Money('€', date_b)
Aud = Money(Currency.AUD, date_a)

# Operations between instances with different dates return an instance with the base date of the first element
adds = OldEur(10) + Eur(30)
assert adds.amount() == 40
assert adds.on_date == OldEur.base_date

# Operations between instances with different currencies return a result in the base currency
result = Eur(10, '$') + Eur(20, 'CAD')
assert result.currency == Currency.EUR

# Changing the reference dates affects the operation results
assert Eur(10, '$', date_a) + Eur(20, 'CAD', date_a) != Eur(10, '$', date_b) + Eur(20, 'CAD', date_b)

# Perform various arithmetic operations
assert Aud(10) + Eur(20) == Aud(39.70) == Eur(39.7, 'aud')
assert Eur(20) + Aud(10) == Eur(26.73)
assert (Aud(10) + Eur(20)).currency == Currency.AUD
assert (Eur(20) + Aud(10)).currency == Currency.EUR
assert Eur(20, 'aud') + Eur(20, 'gbp') == Aud(20, 'aud') + Aud(20, 'gbp')

Using a Single Money Class

In normal use, you will probably create a single Money class with your preferred base currency and use it to handle monetary values in various currencies:

Eur = Money(Currency.EUR)

price_eur = Eur(100)  # €100
price_usd = Eur(120, Currency.USD)  # $120
price_gbp = Eur(80, '£')  # £80

total = price_eur + price_usd + price_gbp
assert str(total) == '€304.71'  # Total in the base currency (EUR)

assert price_usd.currency == Currency.USD
assert price_gbp.currency == Currency.GBP

Configuring Exchange Rates

Dated Money provides flexibility in configuring exchange rates through environment variables:

  • DMON_RATES_CACHE: Set this to a directory where the library can maintain a cache of exchange rates (stored in an SQLite database).

  • DMON_EXCHANGERATE_API_KEY: If the rates file for a given date is not found in the repository or cache, the library will attempt to download it from https://exchangerate-api.com. Set this environment variable to your API key. Note that you may need a paid account to download historical data.

  • DMON_RATES_REPO: Set this to a directory containing a git repository with the exchange rates in a money subdirectory. The rates should be stored in files named yyyy-mm-dd-rates.json, and contain a dictionary like:

    {
     "conversion_rates":{
      "USD":1,
      "AED":3.6725,
      "AFN":71.3141,
    ...}
    }

Creating the Cache Database

To create the cache database, follow these steps:

  1. Set the DMON_RATES_CACHE environment variable:

    export DMON_RATES_CACHE=~/.dmon
    
  2. Create the database cache table:

    dmon-rates --create-table
    

If you have a paid API key for https://exchangerate-api.com, you can set the DMON_EXCHANGERATE_API_KEY environment variable and create your cache with:

dmon-rates --fetch-rates 2021-10-10:2021-10-20

Contributing

Contributions are welcome! If you find any issues or have suggestions for improvements, please open an issue or submit a pull request on the GitHub repository.

License

Dated Money is released under the MIT License.

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

dated_money-1.0.1.tar.gz (13.9 kB view details)

Uploaded Source

Built Distribution

dated_money-1.0.1-py3-none-any.whl (13.4 kB view details)

Uploaded Python 3

File details

Details for the file dated_money-1.0.1.tar.gz.

File metadata

  • Download URL: dated_money-1.0.1.tar.gz
  • Upload date:
  • Size: 13.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.2 CPython/3.12.2 Darwin/23.3.0

File hashes

Hashes for dated_money-1.0.1.tar.gz
Algorithm Hash digest
SHA256 c20ebe19941a6a079365e8e8b98f3bd634bc574607cb765afc021279f8731ed7
MD5 97f97557803aee9cccc49a9e651bfb46
BLAKE2b-256 294b89201107edd60b7d8b93294b6106951dc6b18ab4e07390b406a5769c1141

See more details on using hashes here.

File details

Details for the file dated_money-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: dated_money-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 13.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.2 CPython/3.12.2 Darwin/23.3.0

File hashes

Hashes for dated_money-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e7601be783684d114009dd31f75023eee16993d3305a3846b4f298424d9e349d
MD5 740d899266b75b1790249f092a208f2b
BLAKE2b-256 0191cb919465533dfeff9ad86934a8779a88b62c6799458a21756f33213035c2

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