finlib 0.0.10

Quant finance functions implemented in Rust
Documentation
#[cfg(feature = "std")]
use crate::derivatives::options::blackscholes::OptionVariables;
use crate::derivatives::options::{IOption, OptionGreeks, OptionStyle, OptionType};
use crate::derivatives::TradeSide;
use crate::price::enums::Side;
use crate::price::payoff::Payoff;
use crate::price::payoff::Premium;
use crate::price::payoff::Profit;
use crate::{impl_premium, impl_premium_profit, impl_side};
use bon::Builder;
#[cfg(feature = "py")]
use pyo3::prelude::*;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[cfg(feature = "wasm")]
use wasm_bindgen::prelude::*;

#[cfg_attr(feature = "wasm", wasm_bindgen)]
#[cfg_attr(feature = "py", pyclass(get_all, eq, ord))]
#[cfg_attr(feature = "ffi", repr(C))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Builder, Debug, Copy, Clone, PartialEq, PartialOrd)]
pub struct OptionContract {
    pub option_type: OptionType,
    pub option_style: OptionStyle,
    pub strike: f64,
    pub premium: f64,
    pub side: Side,
    pub greeks: Option<OptionGreeks>,
}

impl_side!(OptionContract);
impl_premium!(OptionContract);
impl_premium_profit!(f64, OptionContract);

impl Payoff<f64> for OptionContract {
    fn payoff(&self, underlying: f64) -> f64 {
        match (self.option_type, self.side) {
            (OptionType::Call, Side::Buy) => (underlying - self.strike).max(0.0),
            (OptionType::Call, Side::Sell) => -(underlying - self.strike).max(0.0),
            (OptionType::Put, Side::Buy) => (self.strike - underlying).max(0.0),
            (OptionType::Put, Side::Sell) => -(self.strike - underlying).max(0.0),
        }
    }
}

impl IOption for OptionContract {
    fn option_type(&self) -> OptionType {
        self.option_type
    }

    fn option_style(&self) -> OptionStyle {
        self.option_style
    }

    fn price(&self) -> f64 {
        self.premium
    }

    fn strike(&self) -> f64 {
        self.strike
    }
}

impl OptionContract {
    pub fn from(
        option_type: OptionType,
        option_style: OptionStyle,
        side: Side,
        strike: f64,
        premium: f64,
    ) -> Self {
        Self {
            option_type,
            option_style,
            side,
            strike,
            premium,
            greeks: None,
        }
    }

    #[cfg(feature = "std")]
    pub fn from_vars(
        vars: &OptionVariables,
        option_type: OptionType,
        option_style: OptionStyle,
        side: Side,
    ) -> Self {
        Self::builder()
            .option_type(option_type)
            .option_style(option_style)
            .side(side)
            .premium(f64::NAN)
            .strike(vars.strike_price)
            .build()
    }

    pub fn will_be_exercised(&self, underlying: f64) -> bool {
        match self.option_type {
            OptionType::Call => self.strike < underlying,
            OptionType::Put => self.strike > underlying,
        }
    }
}