A powerful Python library for financial calculations, including cash flow analysis, asset valuation, and portfolio metrics.
Project description
AssetLab
AssetLab is a powerful Python library for financial calculations, including cash flow analysis, asset valuation, and portfolio metrics.
🌍 Multilingual Support: This project supports both English and Russian languages. See README_ru.md for Russian documentation.
🚀 Features
💰 Cash Flow Analysis (CashFlow)
- XNPV - Net Present Value for irregular cash flows
- XIRR - Internal Rate of Return
- MIRR - Modified Internal Rate of Return
- DPP - Discounted Payback Period
- Duration - Macaulay and Modified
- Profitability Index and Payback Period
- Visualization of cash flows
- Export to pandas DataFrame
🏦 Deposit Modeling (Deposit)
- Interest capitalization and payment
- Deposits and partial withdrawals
- Various interest compounding frequencies
- Conversion to CashFlow for analysis
📈 Bond Modeling (Bond)
- Fixed and floating coupons
- Amortization and early redemption
- Support for caps and floors on floating rates
- Functional base rates
- YTM, current yield, duration calculations
📦 Installation
From Source
git clone https://github.com/your-username/AssetLab.git
cd AssetLab
pip install -e .
Dependencies
- Python 3.9+
- pandas >= 1.5.0
- numpy >= 1.23.0
- pydantic >= 2.0.0
- scipy >= 1.9.0
- matplotlib >= 3.7.0
🎯 Quick Start
Bond Investment Analysis
import pandas as pd
from assetlab import CashFlow, Payment
# Create a bond cash flow
bond_cf = CashFlow(payments=[
Payment(date=pd.Timestamp('2024-01-15'), amount=-980), # Purchase
Payment(date=pd.Timestamp('2025-01-15'), amount=60), # 1st coupon
Payment(date=pd.Timestamp('2026-01-15'), amount=60), # 2nd coupon
Payment(date=pd.Timestamp('2027-01-15'), amount=1060), # 3rd coupon + redemption
])
# Calculate key metrics
discount_rate = 0.05
npv = bond_cf.xnpv(discount_rate)
irr = bond_cf.xirr()
duration = bond_cf.modified_duration(yield_rate=irr)
print(f"NPV: {npv:.2f}")
print(f"IRR: {irr:.2%}")
print(f"Duration: {duration:.2f} years")
Bank Deposit Modeling
from assetlab import Deposit, Payment
# Create a deposit with compounding
deposit = Deposit(
principal=100000,
annual_rate=0.08,
start_date=pd.Timestamp('2024-01-01'),
end_date=pd.Timestamp('2026-01-01'),
interest_frequency=4, # Quarterly compounding
replenishments=[
Payment(date=pd.Timestamp('2024-06-15'), amount=20000)
]
)
# Get results
final_value = deposit.final_value()
total_interest = deposit.total_interest()
cashflow = deposit.to_cashflow()
print(f"Final amount: {final_value:.2f}")
print(f"Total interest: {total_interest:.2f}")
📊 Usage Examples
Portfolio Analysis
# Create several assets
bond_cf = CashFlow(payments=[
Payment(date=pd.Timestamp('2024-01-01'), amount=-1000),
Payment(date=pd.Timestamp('2025-01-01'), amount=1100),
])
stock_cf = CashFlow(payments=[
Payment(date=pd.Timestamp('2024-01-01'), amount=-1500),
Payment(date=pd.Timestamp('2024-06-01'), amount=50), # Dividend
Payment(date=pd.Timestamp('2025-01-01'), amount=1600), # Sale
])
# Combine into portfolio
portfolio = bond_cf + stock_cf
# Analyze portfolio
portfolio_npv = portfolio.xnpv(0.05)
portfolio_irr = portfolio.xirr()
print(f"Portfolio NPV: {portfolio_npv:.2f}")
print(f"Portfolio IRR: {portfolio_irr:.2%}")
Cash Flow Visualization
import matplotlib.pyplot as plt
# Create chart
fig, ax = plt.subplots(figsize=(10, 6))
bond_cf.plot(ax=ax, width=20)
ax.set_title("Bond Cash Flow")
plt.show()
📘 Example: Bond Analysis (Bond)
import pandas as pd
from assetlab import Bond, Payment, FloatingRateConfig
# Simple bond with amortization example
bond = Bond(
issue_date=pd.Timestamp('2024-01-01'),
maturity_date=pd.Timestamp('2027-01-01'),
face_value=1000,
coupon_rate=0.07, # 7% annual
coupon_frequency=2, # Semi-annual coupon
amortizations=[
Payment(date=pd.Timestamp('2025-01-01'), amount=200),
Payment(date=pd.Timestamp('2026-01-01'), amount=200)
]
)
# Generate cash flow
cf = bond.to_cashflow()
print(cf.to_dataframe())
# Analyze yield to maturity (YTM) when purchased at 980
ytm = bond.ytm(price=980)
print(f"YTM: {ytm:.2%}")
# Current yield
current_yield = bond.current_yield(price=980)
print(f"Current yield: {current_yield:.2%}")
# Duration
macaulay = bond.macaulay_duration(price=980)
print(f"Macaulay duration: {macaulay:.2f} years")
Floating Rate Bond
# Floating rate configuration
floating_config = FloatingRateConfig(
base_rate=0.03, # Base rate 3%
spread=0.02, # Spread 2%
cap=0.08, # Maximum rate 8%
floor=0.01 # Minimum rate 1%
)
# Floating rate bond
floating_bond = Bond(
issue_date=pd.Timestamp('2024-01-01'),
maturity_date=pd.Timestamp('2029-01-01'),
face_value=1000,
coupon_rate=floating_config,
coupon_frequency=2
)
# Analyze coupon schedule
schedule = floating_bond.get_coupon_schedule()
print("Floating rate bond coupon schedule:")
for item in schedule:
print(f"Period {item['period']}: Effective rate: {item['effective_rate']:.3%}, "
f"Coupon: {item['coupon_amount']:.2f}")
Working with Accrued Interest (AI)
# Analysis on arbitrary date
analysis_date = pd.Timestamp('2024-03-15')
# Coupon dates
next_coupon = bond.next_coupon_date(analysis_date)
prev_coupon = bond.previous_coupon_date(analysis_date)
print(f"Next coupon: {next_coupon}")
print(f"Previous coupon: {prev_coupon}")
# Accrued interest
accrued = bond.accrued_interest(analysis_date)
print(f"Accrued interest on {analysis_date.date()}: {accrued:.2f}")
# Working with clean and dirty prices
dirty_price = 1025.83 # Price with AI
clean_price = bond.clean_price(dirty_price, analysis_date)
print(f"Clean price: {clean_price:.2f}")
# Reverse operation
dirty_price_calc = bond.dirty_price(clean_price, analysis_date)
print(f"Dirty price: {dirty_price_calc:.2f}")
# Current yield with AI
current_yield = bond.current_yield(dirty_price, analysis_date)
print(f"Current yield: {current_yield:.2%}")
Analysis on Arbitrary Date
# Bond analysis on current date (not issue date)
current_date = pd.Timestamp('2024-06-15')
# YTM on current date
ytm_current = bond.ytm(price=950, analysis_date=current_date)
print(f"YTM on {current_date.date()}: {ytm_current:.2%}")
# Duration on current date
duration_current = bond.macaulay_duration(price=950, analysis_date=current_date)
print(f"Duration on {current_date.date()}: {duration_current:.2f} years")
# Price from YTM on current date
price_from_ytm = bond.price_from_ytm(ytm=0.06, analysis_date=current_date)
print(f"Price at 6% YTM on {current_date.date()}: {price_from_ytm:.2f}")
⚙️ Settings
The library supports global settings:
from assetlab import settings
# Change day count basis for calculations
settings.settings.DAY_COUNT = 360.0 # Default is 365.0
🧪 Testing
Running tests:
# All tests
pytest
# With code coverage
tox
# Individual module
pytest tests/test_cashflow.py
📈 Code Coverage
Current test coverage: 96%
assetlab/__init__.py: 100%assetlab/cashflow.py: 96%assetlab/deposit.py: 94%assetlab/bond.py: 97%assetlab/settings.py: 100%
📚 Documentation
Jupyter Notebooks
Detailed usage examples are available in the examples/ folder:
01_investment_analysis.ipynb- investment and portfolio analysis02_deposit_analysis.ipynb- deposit analysis with replenishments03_bond_analysis.ipynb- bond analysis (fixed, floating, amortization, callable)
Russian versions are available in the examples/ru/ folder:
01_investment_analysis.ipynb- investment and portfolio analysis02_deposit_analysis.ipynb- deposit analysis with replenishments03_bond_analysis.ipynb- bond analysis (fixed, floating, amortization, callable)
Sphinx Documentation
Complete API documentation is available in the docs/ folder:
cd docs
make html
open _build/html/index.html
Documentation includes:
- Auto-generated API documentation
- Usage examples
- Detailed description of all classes and methods
🤝 Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
👨💻 Author
Maxim - MaximVUstinov@gmail.com
🔗 Links
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file assetlab-0.1.0.tar.gz.
File metadata
- Download URL: assetlab-0.1.0.tar.gz
- Upload date:
- Size: 37.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd4afac77ab02c0e193a809d873345e7f8321ded2543b8b91fe74d48a70b061f
|
|
| MD5 |
d6c7460973276e2b9969d19c7b82c581
|
|
| BLAKE2b-256 |
cd59387d3eec1f482cbd982a598f8f1d02499ef7e71e60250ee69c14f1c046cb
|
File details
Details for the file assetlab-0.1.0-py3-none-any.whl.
File metadata
- Download URL: assetlab-0.1.0-py3-none-any.whl
- Upload date:
- Size: 21.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c7bf33a9a8c48e32bc9583fdd2c6175b37e9a4ea2b403c9e8b3e6e372df0165d
|
|
| MD5 |
f8bdc8599ba23647bffbee5217a4ae54
|
|
| BLAKE2b-256 |
baafb3d3cf08437eb73c9c9098694fc1085af03a56dbab7494908958ef36c663
|