# How the Strategable Trait Hierarchy Organizes Strategy Capabilities in OptionStratLib

> Understand how the Strategable trait hierarchy in OptionStratLib unifies option strategies. Discover its organization of Greeks, P&L, probability, and visualization for polymorphic handling and compile-time contracts.

- Repository: [Joaquin Bejar Garcia/optionstratlib](https://github.com/joaquinbejar/optionstratlib)
- Tags: internals
- Published: 2026-03-04

---

**The `Strategable` trait hierarchy unifies all option strategies under a single master trait that aggregates specialized sub-traits for Greeks, P&L, probability analysis, and visualization, enabling polymorphic handling while enforcing compile-time capability contracts.**

OptionStratLib models every option strategy as a concrete Rust type implementing the `Strategable` trait hierarchy. This architecture decouples capability definitions from business logic, allowing diverse strategies—from covered calls to iron condors—to expose a uniform API while maintaining specialized implementations.

## The Master `Strategable` Trait in [`src/strategies/base.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/strategies/base.rs)

Located at lines 50-58 in [`src/strategies/base.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/strategies/base.rs), the `Strategable` trait serves as the central abstraction that enforces a comprehensive contract for all option strategies:

```rust
pub trait Strategable:
    Strategies
    + StrategyConstructor
    + Profit
    + Graph
    + ProbabilityAnalysis
    + Greeks
    + DeltaNeutrality
    + PnLCalculator
{
    // default helpers: `info`, `type_name`, `name`
}

```

This trait contains no business logic itself; it requires implementors to satisfy all listed sub-traits. It provides convenience methods—`info()`, `type_name()`, and `name()`—that forward to the `StrategyBasics` structure, ensuring consistent metadata access across all strategy types.

## Core Capability Traits in the Hierarchy

The `Strategable` trait composes nine specialized capability traits, each defined in dedicated modules to enforce separation of concerns.

### Basic Metadata and Validation

- **`BasicAble`** (defined in [`src/strategies/base.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/strategies/base.rs)): Supplies title retrieval and fundamental strategy metadata through methods like `get_title()`.
- **`Validable`** (defined in [`src/strategies/base.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/strategies/base.rs)): Enforces validation logic via `validate()`, ensuring strategy configurations meet structural requirements before calculation.

### Position and Break-Even Management

- **`Positionable`** (defined in [`src/strategies/base.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/strategies/base.rs)): Grants access to the collection of `Position` structs and handles quantity calculations.
- **`BreakEvenable`** (defined in [`src/strategies/base.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/strategies/base.rs)): Manages break-even price points through `get_break_even_points()` and `update_break_even_points()`.
- **`Strategies`** (defined in [`src/strategies/base.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/strategies/base.rs)): Aggregates profit/loss, cost, price-range, and volume calculations, building upon `Validable`, `Positionable`, `BreakEvenable`, and `BasicAble`.

### Analytics and Visualization

- **`Profit`** (located in [`src/pricing/payoff.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/pricing/payoff.rs)): Calculates profit at any underlying price via `calculate_profit_at()`.
- **`Graph`** (located in [`src/visualization/default.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/visualization/default.rs)): Provides `graph_data()` and optional `graph_config()` for plot-ready output.
- **`ProbabilityAnalysis`** (located in [`src/strategies/probabilities/core.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/strategies/probabilities/core.rs)): Generates structured outcome-probability reports for risk assessment.
- **`Greeks`** (located in [`src/greeks/equations.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/greeks/equations.rs)): Aggregates delta, gamma, vega, theta, and rho calculations across all strategy legs.
- **`DeltaNeutrality`** (located in [`src/strategies/delta_neutral/model.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/strategies/delta_neutral/model.rs)): Checks and enforces delta-neutral positioning utilities.
- **`PnLCalculator`** (located in [`src/pnl/traits.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/pnl/traits.rs)): Tracks realized and unrealized profit/loss with transaction handling.

### Strategy Construction

- **`StrategyConstructor`** (defined in [`src/strategies/build/traits.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/strategies/build/traits.rs)): Enables generic conversion from a slice of `Position` structs into concrete strategy types via the `get_strategy()` method.

## Concrete Implementation Example: `ShortStrangle`

The `ShortStrangle` strategy in [`src/strategies/short_strangle.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/strategies/short_strangle.rs) demonstrates how concrete types integrate into the hierarchy. It implements `Strategable` by providing the required `info()` method:

```rust
impl Strategable for ShortStrangle {
    fn info(&self) -> Result<StrategyBasics, StrategyError> {
        Ok(StrategyBasics {
            name: self.name.clone(),
            kind: self.kind.clone(),
            description: self.description.clone(),
        })
    }
}

```

Because `ShortStrangle` also implements `BasicAble` (providing `get_title()`), `Positionable` (via the internal `legs` vector), `BreakEvenable` (with custom break-even logic), `StrategyConstructor` (through the generic builder), and the remaining analytics traits, the compiler recognizes it as a fully-featured strategy satisfying the complete `Strategable` contract.

## Benefits of the Trait Composition Pattern

This hierarchical design delivers three critical architectural advantages:

**Extensibility without breakage** — Adding new capabilities requires only defining a new trait and appending it to the `Strategable` requirements. Existing strategies automatically gain the new method signature at compile time without breaking changes.

**Separation of concerns** — Each trait isolates a single domain (Greek mathematics, visualization, P&L accounting). Unit tests can target individual trait implementations rather than monolithic strategy objects.

**Runtime polymorphism** — The library stores heterogeneous strategies behind boxed trait objects (`Box<dyn Strategable>`) while retaining access to all aggregated methods. The generic builder in [`strategies/build/model.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/strategies/build/model.rs) (line 72) leverages this to return concrete strategy instances through a uniform interface.

## Implementing a Custom Strategy

Developers can create new strategies by implementing the required traits. The following example shows a minimal "Zero-Cost" strategy implementing the full hierarchy:

```rust
use optionstratlib::strategies::{
    BasicAble, Strategies, Positionable, BreakEvenable, Validable,
    StrategyConstructor, Greeks, Profit, Graph, ProbabiltyAnalysis,
    DeltaNeutrality, PnLCalculator, StrategyBasics, StrategyError,
};
use optionstratlib::model::Position;

/// Minimal “Zero‑Cost” strategy that is only profit‑aware.
pub struct ZeroCost {
    pub name: String,
    pub kind: StrategyType,
    pub description: String,
    pub legs: Vec<Position>,
}

// ----- BasicAble -------------------------------------------------
impl BasicAble for ZeroCost {
    fn get_title(&self) -> String {
        format!("Zero‑Cost: {}", self.kind)
    }
}

// ----- Positionable -----------------------------------------------
impl Positionable for ZeroCost {
    fn get_positions(&self) -> &Vec<Position> {
        &self.legs
    }
}

// ----- BreakEvenable (use default error) --------------------------
impl BreakEvenable for ZeroCost {}

// ----- Validable --------------------------------------------------
impl Validable for ZeroCost {
    fn validate(&self) -> bool {
        // a zero‑cost strategy must have net premium = 0
        self.get_total_premium() == Decimal::ZERO
    }
}

// ----- Strategies -------------------------------------------------
impl Strategies for ZeroCost {}

// ----- StrategyConstructor (use default NotImplemented) ----------
impl StrategyConstructor for ZeroCost {}

// ----- Profit (custom implementation) -----------------------------
impl Profit for ZeroCost {
    fn calculate_profit_at(&self, price: &Positive) -> Result<Decimal, PricingError> {
        // simple sum of payoff of each leg at `price`
        self.legs
            .iter()
            .map(|leg| leg.calculate_payoff(price))
            .sum()
    }
}

// ----- Graph (use default from `visualization::default`) ---------
impl Graph for ZeroCost {}

// ----- ProbabilityAnalysis (use default NotImplemented) ----------
impl ProbabiltyAnalysis for ZeroCost {}

// ----- DeltaNeutrality (use default NotImplemented) -------------
impl DeltaNeutrality for ZeroCost {}

// ----- PnLCalculator (use default NotImplemented) ---------------
impl PnLCalculator for ZeroCost {}

// ----- Strategable (only need to supply `info`) ---------------
impl Strategable for ZeroCost {
    fn info(&self) -> Result<StrategyBasics, StrategyError> {
        Ok(StrategyBasics {
            name: self.name.clone(),
            kind: self.kind.clone(),
            description: self.description.clone(),
        })
    }
}

```

All required traits are satisfied, allowing `ZeroCost` to function as `dyn Strategable` within the library ecosystem.

## Runtime Polymorphism with Boxed Strategies

User code can handle multiple strategy types uniformly through trait objects. The following pattern demonstrates building strategies from raw positions:

```rust
use optionstratlib::strategies::{Strategable, StrategyConstructor};
use optionstratlib::model::Position;

/// Build a strategy from raw positions (the builder decides the concrete type)
fn build_from_legs(positions: &[Position]) -> Box<dyn Strategable> {
    // The generic builder tries each concrete strategy in order.
    // `ShortStrangle` is one of many.
    ShortStrangle::get_strategy(positions)
        .or_else(|_| ShortPut::get_strategy(positions))
        .unwrap()
}

// ---- runtime usage -------------------------------------------------
let legs: Vec<Position> = vec![/* ... */]; // user‑provided data
let strat = build_from_legs(&legs);

println!("Strategy: {}", strat.name());
let profit = strat.calculate_profit_at(&Positive::new(150.0).unwrap()).unwrap();
println!("Profit @ 150 = {}", profit);

```

The caller interacts solely with the `Strategable` interface, while the concrete implementation (whether `ShortStrangle`, `ShortPut`, or any other variant) remains encapsulated.

## Summary

- **`Strategable`** serves as the master trait in [`src/strategies/base.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/strategies/base.rs), aggregating nine specialized capability traits into a unified contract.
- Sub-traits like **`Greeks`**, **`Profit`**, and **`ProbabilityAnalysis`** isolate specific domains, enabling modular testing and extension.
- Concrete strategies such as **`ShortStrangle`** implement `Strategable` by satisfying all sub-trait requirements, typically providing custom logic only where differentiated.
- The hierarchy supports **runtime polymorphism** via `Box<dyn Strategable>`, allowing generic strategy builders to return heterogeneous types through a single interface.
- New capabilities integrate seamlessly by adding traits to the hierarchy, with compile-time enforcement ensuring all strategies expose consistent APIs.

## Frequently Asked Questions

### What is the `Strategable` trait in OptionStratLib?

The `Strategable` trait is the central abstraction defined in [`src/strategies/base.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/strategies/base.rs) that defines the complete contract for option strategies. It aggregates nine specialized sub-traits—including `Greeks`, `Profit`, and `PnLCalculator`—into a single interface that guarantees uniform behavior across all strategy types while permitting specialized implementations.

### Which sub-traits does `Strategable` require?

`Strategable` requires **`Strategies`**, **`StrategyConstructor`**, **`Profit`**, **`Graph`**, **`ProbabilityAnalysis`**, **`Greeks`**, **`DeltaNeutrality`**, and **`PnLCalculator`**. These traits cover validation, position management, break-even calculation, profit surfaces, visualization, Greek analytics, delta-neutral checks, and P&L accounting respectively.

### How does OptionStratLib handle different strategy types at runtime?

The library leverages trait objects (`Box<dyn Strategable>`) to store heterogeneous strategies behind a unified pointer. As implemented in [`strategies/build/model.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/strategies/build/model.rs), generic builders can attempt construction against multiple concrete types and return the successful match as a boxed trait object, enabling polymorphic profit calculations and Greek analysis without knowing the concrete type at compile time.

### Where can I find the source files for the trait hierarchy?

The master trait resides in [`src/strategies/base.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/strategies/base.rs) (lines 50-58). Specialized traits are distributed across **[`src/greeks/equations.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/greeks/equations.rs)** (Greeks), **[`src/pnl/traits.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/pnl/traits.rs)** (PnL), **[`src/pricing/payoff.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/pricing/payoff.rs)** (Profit), **[`src/visualization/default.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/visualization/default.rs)** (Graph), **[`src/strategies/probabilities/core.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/strategies/probabilities/core.rs)** (ProbabilityAnalysis), **[`src/strategies/delta_neutral/model.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/strategies/delta_neutral/model.rs)** (DeltaNeutrality), and **[`src/strategies/build/traits.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/strategies/build/traits.rs)** (StrategyConstructor).