Skip to main content

AssetLab

Python 3.9+ License: MIT Code Coverage

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 analysis
  • 02_deposit_analysis.ipynb - deposit analysis with replenishments
  • 03_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 analysis
  • 02_deposit_analysis.ipynb - deposit analysis with replenishments
  • 03_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

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. 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

Metadata

Release files for assetlab 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for assetlab 0.1.0
File Size Uploaded Provenance
assetlab-0.1.0.tar.gz 37.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for assetlab 0.1.0
File Interpreter ABI Platform
assetlab-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 59.6 kB

Release files / assetlab-0.1.0.tar.gz

Download URL assetlab-0.1.0.tar.gz
Size 37.7 kB
Tags Source
SHA-256 checksum
How to use checksums
fd4afac77ab02c0e193a809d873345e7f8321ded2543b8b91fe74d48a70b061f
BLAKE2b-256 checksum
How to use checksums
cd59387d3eec1f482cbd982a598f8f1d02499ef7e71e60250ee69c14f1c046cb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.0

Release files / assetlab-0.1.0-py3-none-any.whl

Download URL assetlab-0.1.0-py3-none-any.whl
Size 21.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c7bf33a9a8c48e32bc9583fdd2c6175b37e9a4ea2b403c9e8b3e6e372df0165d
BLAKE2b-256 checksum
How to use checksums
baafb3d3cf08437eb73c9c9098694fc1085af03a56dbab7494908958ef36c663
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.0

Security for assetlab 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page