Skip to main content

Tactical asset allocation library with Rust backend

Project description

AllocationO2

Tactical asset allocation library with Rust backend

Project Structure

The project consists of two main parts:

  1. Rust Backend (rust_backend/): Core functionality implemented in Rust

    • Fast and efficient portfolio optimization algorithms
    • Asset allocation strategies
    • Portfolio analytics
  2. Python Package (allocation_o2/): Python interface using PyO3

    • User-friendly API for Python users
    • Data visualization and analysis
    • Integration with data sources

Features

  • High-performance asset allocation strategies implemented in Rust
  • Pythonic interface for easy integration with data science workflows
  • Support for various allocation strategies:
    • Equal Weight
    • Random Weight (with optional seed for reproducibility)
    • More strategies coming soon...
  • Ability to compile custom Rust strategy files

Installation

Requirements

  • Rust (latest stable)
  • Python 3.10+
  • C compiler (for building Rust extensions)

From Source

Clone the repository and install:

git clone https://github.com/VladKochetov007/allocation_o2
cd AllocationO2
make install

Development Mode

For development, install in editable mode:

make develop

Usage

Basic Example

import numpy as np
from allocation_o2 import create_allocator_class

# Create your own allocation strategy
class MyAllocationStrategy:
    def __init__(self):
        self.min_observations = 1
        
    def predict(self, prices):
        # Your allocation strategy logic here
        n_assets = prices.shape[0]
        return np.ones(n_assets) / n_assets

# Create your own allocation strategy
MyAllocator = create_allocator_class(
    MyAllocationStrategy,
    param_info={
        "min_observations": (int, 1),
    }
)

# Create an allocator instance
allocator = MyAllocator()

# Generate price data
prices = np.random.random((5, 100))  # 5 assets, 100 time steps

# Get allocation weights
weights = allocator.predict(prices)
print(weights)  # Array of weights, sum of which equals 1.0

Custom Rust Strategies

You can create custom allocation strategies directly in Rust for better performance.

Compiling a Custom Rust Strategy

Use the command line interface to compile your custom Rust strategy:

python -m allocation_o2 compile path/to/your_strategy.rs

This will compile your Rust file into a shared library (.so) and place it in the same directory. You can specify an alternative output location:

python -m allocation_o2 compile path/to/your_strategy.rs -o path/to/output.so

Creating a Custom Rust Strategy

To create a custom Rust strategy, use the template in the examples directory (examples/strategy_template.rs) as a starting point. Your strategy must implement the AllocationStrategy trait and be registered with PyO3.

Example rust strategy:

use ndarray::ArrayD;
use pyo3::prelude::*;

// Import from allocation_o2
use allocation_o2::allocation::traits::AllocationStrategy;
use allocation_o2::register_strategy;
use allocation_o2::allocation::py_bindings::{numpy_to_ndarray, ndarray_to_numpy};

#[pyclass]
pub struct MyCustomStrategy {
    #[pyo3(get, set)]
    pub min_observations: usize,
}

#[pymethods]
impl MyCustomStrategy {
    #[new]
    fn new() -> Self {
        Self {
            min_observations: 1,
        }
    }
    
    fn predict(&self, py: Python, input: &PyAny) -> PyResult<PyObject> {
        let input_array = numpy_to_ndarray(py, input)?;
        let output_array = self.predict_impl(&input_array);
        ndarray_to_numpy(py, output_array)
    }
}

impl AllocationStrategy for MyCustomStrategy {
    fn min_observations(&self) -> usize {
        self.min_observations
    }
    
    fn predict(&self, input: &ArrayD<f64>) -> ArrayD<f64> {
        self.predict_impl(input)
    }
}

impl MyCustomStrategy {
    fn predict_impl(&self, input: &ArrayD<f64>) -> ArrayD<f64> {
        // Your allocation strategy logic here
        // For demonstration, we'll use equal weights
        let shape = input.shape();
        let n_assets = shape[1];
        
        let mut weights = ArrayD::zeros(vec![shape[0], shape[1]]);
        let equal_weight = 1.0 / n_assets as f64;
        
        for w in weights.iter_mut() {
            *w = equal_weight;
        }
        
        weights
    }
}

#[pymodule]
fn my_custom_strategy(_py: Python, m: &PyModule) -> PyResult<()> {
    register_strategy!(m, MyCustomStrategy);
    Ok(())
}

Examples

Examples are not included in the package installation and should be created by the user themselves. The repository contains examples for reference:

# Run random weight example (only from source code)
make build_examples

Creating a wheel package

To create a wheel package for distribution:

make wheel

License

This project is licensed under the MIT License - see the LICENSE file for details.

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

allocation_o2-1.0.0.tar.gz (2.9 MB view details)

Uploaded Source

Built Distribution

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

allocation_o2-1.0.0-py3-none-any.whl (3.0 MB view details)

Uploaded Python 3

File details

Details for the file allocation_o2-1.0.0.tar.gz.

File metadata

  • Download URL: allocation_o2-1.0.0.tar.gz
  • Upload date:
  • Size: 2.9 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.12.9

File hashes

Hashes for allocation_o2-1.0.0.tar.gz
Algorithm Hash digest
SHA256 aece0ca1b777f05c67a552dd1a2e9171393ab4f401fce5e7eafd77fa79658d86
MD5 6524765b6f64794a1d5af1b4b29fc566
BLAKE2b-256 2dbfc5d8922a4a488037f5544343648473ca1b09146b09a934e926e821269e2d

See more details on using hashes here.

File details

Details for the file allocation_o2-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: allocation_o2-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 3.0 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.12.9

File hashes

Hashes for allocation_o2-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1c7b54c80cca821357f1ec1d86993e0a8ed38d04d88b9597099a6e4e6b4afbc5
MD5 4d1de2ef80b7dd7602fdc161e960a79c
BLAKE2b-256 412a4226fa1741454b75123111df43d2e2d06c555b1e4253f5261c5e3121d0c4

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