use crate::chains::OptionChainBuildParams;
use positive::Positive;
use pretty_simple_display::{DebugPretty, DisplaySimple};
use serde::{Deserialize, Serialize};
#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
pub struct OptionSeriesBuildParams {
pub(crate) chain_params: OptionChainBuildParams,
pub(crate) series: Vec<Positive>,
}
impl OptionSeriesBuildParams {
#[inline]
#[must_use]
pub fn new(chain_params: OptionChainBuildParams, series: Vec<Positive>) -> Self {
Self {
chain_params,
series,
}
}
#[inline]
pub fn set_underlying_price(&mut self, price: &Positive) {
let price = Some(Box::new(*price));
self.chain_params.set_underlying_price(price);
}
#[inline]
pub fn set_implied_volatility(&mut self, volatility: Positive) {
self.chain_params.set_implied_volatility(volatility);
}
}
#[cfg(test)]
mod tests {
use super::*;
use positive::{Positive, pos_or_panic, spos};
use crate::ExpirationDate;
use crate::chains::utils::OptionDataPriceParams;
use rust_decimal_macros::dec;
#[test]
fn test_display_empty_series() {
let expiration = ExpirationDate::Days(pos_or_panic!(30.0));
let price_params = OptionDataPriceParams::new(
Some(Box::new(Positive::HUNDRED)),
Some(expiration),
Some(dec!(0.05)),
spos!(0.02),
Some("AAPL".to_string()),
);
let chain_params = OptionChainBuildParams::new(
"AAPL".to_string(),
spos!(1000.0),
10,
spos!(5.0),
dec!(-0.2),
dec!(0.1),
pos_or_panic!(0.02),
2,
price_params,
pos_or_panic!(0.2),
);
let params = OptionSeriesBuildParams {
chain_params,
series: vec![],
};
let result = r#"{"chain_params":{"symbol":"AAPL","volume":1000,"chain_size":10,"strike_interval":5,"skew_slope":"-0.2","smile_curve":"0.1","spread":0.02,"decimal_places":2,"price_params":{"underlying_price":100,"expiration_date":{"days":30.0},"risk_free_rate":"0.05","dividend_yield":0.02,"underlying_symbol":"AAPL"},"implied_volatility":0.2},"series":[]}"#;
assert_eq!(params.to_string(), result);
}
#[test]
fn test_debug_empty_series() {
let expiration = ExpirationDate::Days(pos_or_panic!(30.0));
let price_params = OptionDataPriceParams::new(
Some(Box::new(Positive::HUNDRED)),
Some(expiration),
Some(dec!(0.05)),
spos!(0.02),
Some("AAPL".to_string()),
);
let chain_params = OptionChainBuildParams::new(
"AAPL".to_string(),
spos!(1000.0),
10,
spos!(5.0),
dec!(-0.2),
dec!(0.1),
pos_or_panic!(0.02),
2,
price_params,
pos_or_panic!(0.2),
);
let params = OptionSeriesBuildParams {
chain_params,
series: vec![],
};
let result = r#"{
"chain_params": {
"symbol": "AAPL",
"volume": 1000,
"chain_size": 10,
"strike_interval": 5,
"skew_slope": "-0.2",
"smile_curve": "0.1",
"spread": 0.02,
"decimal_places": 2,
"price_params": {
"underlying_price": 100,
"expiration_date": {
"days": 30.0
},
"risk_free_rate": "0.05",
"dividend_yield": 0.02,
"underlying_symbol": "AAPL"
},
"implied_volatility": 0.2
},
"series": []
}"#;
let debug_result = format!("{params:?}");
assert_eq!(debug_result, result);
}
}