Skip to main content

schwab_cli/options/
types.rs

1use serde::{Deserialize, Serialize};
2
3/// Vertical spread parameters (LLM / rules facing).
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct VerticalParams {
6    pub underlying: String,
7    pub expiry: String,
8    /// put_credit | put_debit | call_credit | call_debit
9    #[serde(rename = "type")]
10    pub spread_type: String,
11    pub short_strike: f64,
12    pub long_strike: f64,
13    pub contracts: f64,
14    #[serde(default, skip_serializing_if = "Option::is_none")]
15    pub limit_credit: Option<f64>,
16    #[serde(default, skip_serializing_if = "Option::is_none")]
17    pub limit_debit: Option<f64>,
18    #[serde(default)]
19    pub duration: Option<String>,
20    #[serde(default)]
21    pub session: Option<String>,
22}
23
24/// Iron condor parameters.
25#[derive(Debug, Clone, Serialize, Deserialize)]
26pub struct IronCondorParams {
27    pub underlying: String,
28    pub expiry: String,
29    pub put_short: f64,
30    pub put_long: f64,
31    pub call_short: f64,
32    pub call_long: f64,
33    pub contracts: f64,
34    pub limit_credit: f64,
35    #[serde(default)]
36    pub duration: Option<String>,
37    #[serde(default)]
38    pub session: Option<String>,
39}
40
41#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
42#[serde(rename_all = "snake_case")]
43pub enum StrategyKind {
44    Vertical,
45    IronCondor,
46}
47
48impl StrategyKind {
49    pub fn parse(raw: &str) -> anyhow::Result<Self> {
50        match raw.trim().to_ascii_lowercase().as_str() {
51            "vertical" | "vert" => Ok(Self::Vertical),
52            "iron_condor" | "iron-condor" | "condor" => Ok(Self::IronCondor),
53            other => anyhow::bail!("unknown strategy `{other}` (use vertical or iron_condor)"),
54        }
55    }
56
57    pub fn as_str(self) -> &'static str {
58        match self {
59            Self::Vertical => "vertical",
60            Self::IronCondor => "iron_condor",
61        }
62    }
63}