nautilus_trading/examples/strategies/delta_neutral_vol/config.rs
1// -------------------------------------------------------------------------------------------------
2// Copyright (C) 2015-2026 Nautech Systems Pty Ltd. All rights reserved.
3// https://nautechsystems.io
4//
5// Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6// You may not use this file except in compliance with the License.
7// You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16//! Configuration for the delta-neutral volatility hedger.
17
18use nautilus_model::{
19 enums::TimeInForce,
20 identifiers::{ClientId, InstrumentId, StrategyId},
21};
22
23use crate::strategy::StrategyConfig;
24
25/// Configuration for the delta-neutral short volatility hedger.
26///
27/// Tracks a short OTM call and put (strangle) and delta-hedges with the
28/// underlying perpetual swap. Rehedges when portfolio delta exceeds a
29/// configurable threshold or on a periodic timer.
30#[derive(Debug, Clone, bon::Builder)]
31#[cfg_attr(
32 feature = "python",
33 pyo3::pyclass(module = "nautilus_trader.core.nautilus_pyo3.trading", from_py_object)
34)]
35#[cfg_attr(
36 feature = "python",
37 pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.trading")
38)]
39pub struct DeltaNeutralVolConfig {
40 /// Base strategy configuration.
41 #[builder(default = StrategyConfig {
42 strategy_id: Some(StrategyId::from("DELTA_NEUTRAL_VOL-001")),
43 order_id_tag: Some("001".to_string()),
44 ..Default::default()
45 })]
46 pub base: StrategyConfig,
47 /// Option instrument family (e.g. "BTC-USD").
48 pub option_family: String,
49 /// Hedge instrument ID (e.g. BTC-USD-SWAP.OKX).
50 pub hedge_instrument_id: InstrumentId,
51 /// Data and execution client ID (e.g. "OKX").
52 pub client_id: ClientId,
53 /// Target call delta used by the startup strike heuristic.
54 #[builder(default = 0.20)]
55 pub target_call_delta: f64,
56 /// Target put delta used by the startup strike heuristic.
57 #[builder(default = -0.20)]
58 pub target_put_delta: f64,
59 /// Number of option contracts per leg.
60 #[builder(default = 1)]
61 pub contracts: u64,
62 /// Portfolio delta threshold that triggers a rehedge.
63 #[builder(default = 0.5)]
64 pub rehedge_delta_threshold: f64,
65 /// Periodic rehedge check interval in seconds.
66 #[builder(default = 30)]
67 pub rehedge_interval_secs: u64,
68 /// Optional expiry date filter (e.g. "260327").
69 pub expiry_filter: Option<String>,
70 /// Place strangle entry orders when Greeks are first initialized.
71 /// When false the strategy only hedges externally-entered positions.
72 #[builder(default = true)]
73 pub enter_strangle: bool,
74 /// Implied volatility offset subtracted from mark IV for entry limit
75 /// price. A value of 0.02 sells 2 vol points below mark (more aggressive).
76 #[builder(default = 0.0)]
77 pub entry_iv_offset: f64,
78 /// Time-in-force for strangle entry orders.
79 #[builder(default = TimeInForce::Gtc)]
80 pub entry_time_in_force: TimeInForce,
81 /// Tick offset from the option ask used for premium-priced entry orders.
82 /// When set, the strategy does not pass IV params to the adapter.
83 pub entry_premium_offset_ticks: Option<i32>,
84 /// Param key for implied volatility passed to `submit_order`.
85 /// Adapter-specific: Bybit uses `"order_iv"`, OKX uses `"px_vol"`.
86 #[builder(default = "px_vol".to_string())]
87 pub iv_param_key: String,
88}