Skip to main content

Tool to keep balance a portfolio of securities while investing.

Project description

foliotrack Logo

foliotrack is a Python package to manage, optimize and rebalance securities, including Exchange-Traded Funds (ETFs). Given a set of securities and their target allocation weights, the packages methods compute the optimal investment adjustments required to align the portfolio with the desired strategy.

Key Features

  • Portfolio Management:

    • Create, load, and save portfolios in JSON format
    • Track multiple securities across different currencies
    • Automatic price updates from Yahoo Finance
    • Real-time currency conversion using ECB data
    • Buy and sell securities with automatic value adjustments
    • Track target, actual, and final allocation shares
  • Mathematical Optimization:

    • Mixed-Integer Quadratic Programming (MIQP) for automatic rebalancing towards target allocations
    • Investment constraints (e.g., minimum investment percentage)
    • Solver integration with CVXPY and PySCIPOpt
  • Multi-Currency Support:

    • Real-time exchange rates from European Central Bank
    • Automatic currency conversion for portfolio valuation
    • Support for 150+ global currencies
    • Currency symbol and name resolution
  • Real-Time Data Integration:

    • Security prices via yfinance API
    • Company information and metadata retrieval
    • Currency conversion via ecbdata
    • Automatic price and value updates

Use Case

Ideal for investors, financial advisors, and algorithmic traders seeking to:

  • Automated Rebalancing – Maintains target asset allocations with minimal manual intervention, ensuring alignment with investment strategies.
  • Multi-Currency Support – Dynamically adjusts for exchange rate fluctuations, enabling accurate valuation and rebalancing of global portfolios.

Project Structure

Core Modules

  • main.py: Example usage and entry point with portfolio creation and management examples.
  • foliotrack/Currency.py: Currency management with symbol resolution, exchange rates, and ECB data integration.
  • foliotrack/Security.py: Security class with real-time price updates, trading operations, and market data integration.
  • foliotrack/Portfolio.py: Portfolio management with multi-currency support, security tracking, and allocation management.
  • foliotrack/Equilibrate.py: Portfolio optimization using MIQP for efficient rebalancing.

Data

  • foliotrack/data/currencies.json: Database of 150+ currencies with symbols and metadata.
  • Portfolios/: Directory for storing portfolio JSON files.
    • investment_example.json: Example portfolio configuration.

Tests

  • tests/foliotrack/: Comprehensive test suite.
    • test_currency.py: Currency operations and exchange rate tests.
    • test_portfolio.py: Portfolio management and serialization tests.
    • test_security.py: Security operations and market data tests.
    • test_equilibrate.py: Portfolio optimization tests.

Installation

Clone the repository from Github:

git clone git@github.com:PhDFlo/foliotrack.git

In the foliotrack folder create the python environment using uv:

uv sync
source .venv/bin/activate

Usage Examples

foliotrack provides a comprehensive Python API for portfolio management. Here are some common use cases:

import logging
from foliotrack.Security import Security
from foliotrack.Portfolio import Portfolio
from foliotrack.Equilibrate import Equilibrate

logging.basicConfig(level=logging.INFO)

def main():
    portfolio = Portfolio()

    # Buy some seucirties
    portfolio.buy_security("AIR.PA", quantity=20.0, price=200.0, fill=True)
    portfolio.buy_security("NVDA", quantity=1.0, price=600.0, fill=True)
    portfolio.buy_security("MC.PA", quantity=1.0, price=300.0, fill=True)

    # Sell some of them
    portfolio.sell_security("AIR.PA", 3.0)

    # Set target shares
    portfolio.set_target_share("AIR.PA", 0.5)
    portfolio.set_target_share("NVDA", 0.2)
    portfolio.set_target_share("MC.PA", 0.3)

    # Save in JSON file
    portfolio.to_json("Portfolios/investment_example.json")

    # Solve for equilibrium
    solve_equilibrium(portfolio, investment_amount=1000.0, min_percent_to_invest=0.99)

    # Log portfolio info
    info = portfolio.get_portfolio_info()
    logging.info("Portfolio info:")
    for security_info in info:
        logging.info("Security:")
        for k, v in security_info.items():
            logging.info(f"  {k}: {v}")

if __name__ == "__main__":
    main()

Which produces the following output:

INFO:root:Security 'AIR.PA' added to portfolio with quantity 20.0.
INFO:root:Exchange rate USD → EUR on latest: 0.8655
INFO:root:Security 'NVDA' added to portfolio with quantity 1.0.
INFO:root:Exchange rate USD → EUR on latest: 0.8655
INFO:root:Security 'MC.PA' added to portfolio with quantity 1.0.
INFO:root:Exchange rate USD → EUR on latest: 0.8655
INFO:root:Sold 3.0 units of security 'AIR.PA'. New number held: 17.0.
INFO:root:Exchange rate USD → EUR on latest: 0.8655
INFO:root:Portfolio saved to Portfolios/investment_example.json
INFO:root:Optimisation status: optimal
INFO:root:Number of each Security to buy:
INFO:root:  Airbus SE: 3 units
INFO:root:  NVIDIA Corporation: 2 units
INFO:root:  LVMH Moët Hennessy - Louis Vuitton, Société Européenne: 0 units
INFO:root:Amount to spend and final share of each Security:
INFO:root:  Airbus SE: 640.20€, Final share = 0.7895
INFO:root:  NVIDIA Corporation: 350.52€, Final share = 0.0973
INFO:root:  LVMH Moët Hennessy - Louis Vuitton, Société Européenne: 0.00€, Final share = 0.1132
INFO:root:Total amount to invest: 990.72€
INFO:root:Portfolio info:
INFO:root:Security:
INFO:root:  name: Airbus SE
INFO:root:  ticker: AIR.PA
INFO:root:  currency: EUR
INFO:root:  symbol: €
INFO:root:  exchange_rate: 1.0
INFO:root:  price_in_security_currency: 213.4
INFO:root:  price_in_portfolio_currency: 213.4
INFO:root:  quantity: 17.0
INFO:root:  number_to_buy: 3
INFO:root:  amount_to_invest: 640.2
INFO:root:  value: 3627.8
INFO:root:  fill: True
INFO:root:  target_share: 0.5
INFO:root:  actual_share: 0.8217
INFO:root:  final_share: 0.7895
INFO:root:Security:
INFO:root:  name: NVIDIA Corporation
INFO:root:  ticker: NVDA
INFO:root:  currency: USD
INFO:root:  symbol: $
INFO:root:  exchange_rate: 0.8655
INFO:root:  price_in_security_currency: 202.49
INFO:root:  price_in_portfolio_currency: 175.26
INFO:root:  quantity: 1.0
INFO:root:  number_to_buy: 2
INFO:root:  amount_to_invest: 350.52
INFO:root:  value: 175.26
INFO:root:  fill: True
INFO:root:  target_share: 0.2
INFO:root:  actual_share: 0.0397
INFO:root:  final_share: 0.0973
INFO:root:Security:
INFO:root:  name: LVMH Moët Hennessy - Louis Vuitton, Société Européenne
INFO:root:  ticker: MC.PA
INFO:root:  currency: EUR
INFO:root:  symbol: €
INFO:root:  exchange_rate: 1.0
INFO:root:  price_in_security_currency: 612.1
INFO:root:  price_in_portfolio_currency: 612.1
INFO:root:  quantity: 1.0
INFO:root:  number_to_buy: 0
INFO:root:  amount_to_invest: 0.0
INFO:root:  value: 612.1
INFO:root:  fill: True
INFO:root:  target_share: 0.3
INFO:root:  actual_share: 0.1386
INFO:root:  final_share: 0.1132

Requirements

  • Python 3.12+
  • numpy - Array operations and mathematical functions
  • cvxpy - Convex optimization modeling
  • pyscipopt - Mixed-integer programming solver

Financial Data Integration

  • yfinance - Real-time market data
  • ecbdata - Currency exchange rates
  • pandas - Data manipulation and analysis

Development and Testing

  • pytest - Unit testing
  • ruff - Code formatting and linting
  • uv - Python package management and virtual environments

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

foliotrack-0.0.5.tar.gz (23.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

foliotrack-0.0.5-py3-none-any.whl (24.0 kB view details)

Uploaded Python 3

File details

Details for the file foliotrack-0.0.5.tar.gz.

File metadata

  • Download URL: foliotrack-0.0.5.tar.gz
  • Upload date:
  • Size: 23.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.9.7

File hashes

Hashes for foliotrack-0.0.5.tar.gz
Algorithm Hash digest
SHA256 2ebf7c6f4e5306fbef7f52f8bf9ed02fda476617df991d9d55f8cf27c9ef7c32
MD5 b803c457e473cb416de6c40d9c8cdfda
BLAKE2b-256 d9f9e1e22b37a134a12ff7ff7c7389825a6a6c8166f28c7b6fca9ca77ff74268

See more details on using hashes here.

File details

Details for the file foliotrack-0.0.5-py3-none-any.whl.

File metadata

  • Download URL: foliotrack-0.0.5-py3-none-any.whl
  • Upload date:
  • Size: 24.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.9.7

File hashes

Hashes for foliotrack-0.0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 222179ad14ddfb5ff19d87c202ddecc44af12cf7e87b5e9fca431d08f35751c2
MD5 d524252a399a993addef31aff9a22eb8
BLAKE2b-256 1e675789aacb7d01279ec2d6280e424a49d599319aa0dcc4e8a4a3fe7aac71b9

See more details on using hashes here.

Supported by

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