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
date_a = '2022-07-14'
Eur = Money(Currency.EUR, date_a)
Aud = Money(base_currency='A$', base_date=date_a)
price_eur = Eur(100)
price_usd = Eur(120, Currency.USD)
price_gbp = Eur(80, '£')
assert Eur(23, '€').cents('eur') == 2300
assert Eur(40).cents('usd') == Dec('4020.100502512562832012897042')
assert Eur(20, '£') == Aud(20, '£')
total = price_eur + price_usd + price_gbp
assert str(total) == '€270.40'
total_usd = total.to(Currency.USD)
assert str(total_usd) == '$303.89'
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)
adds = OldEur(10) + Eur(30)
assert adds.amount() == 40
assert adds.on_date == OldEur.base_date
result = Eur(10, '$') + Eur(20, 'CAD')
assert result.currency == Currency.EUR
assert Eur(10, '$', date_a) + Eur(20, 'CAD', date_a) != Eur(10, '$', date_b) + Eur(20, 'CAD', date_b)
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)
price_usd = Eur(120, Currency.USD)
price_gbp = Eur(80, '£')
total = price_eur + price_usd + price_gbp
assert str(total) == '€304.71'
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:
-
Set the DMON_RATES_CACHE
environment variable:
export DMON_RATES_CACHE=~/.dmon
-
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.