use super::types::ValidationError;
use crate::contracts::TagValue;
use crate::ToField;
pub const MIN_PCT_VOL: f64 = 0.1;
pub const MAX_PCT_VOL: f64 = 0.5;
fn validate_pct_vol(field: &'static str, value: f64) -> Result<(), ValidationError> {
if !(MIN_PCT_VOL..=MAX_PCT_VOL).contains(&value) {
Err(ValidationError::InvalidPercentage {
field,
value,
min: MIN_PCT_VOL,
max: MAX_PCT_VOL,
})
} else {
Ok(())
}
}
fn build_windowed_pct_vol(
strategy: &'static str,
start_pct_vol: Option<f64>,
end_pct_vol: Option<f64>,
start_time: Option<String>,
end_time: Option<String>,
no_take_liq: Option<bool>,
) -> Result<AlgoParams, ValidationError> {
let mut params = Vec::new();
if let Some(v) = start_pct_vol {
validate_pct_vol("start_pct_vol", v)?;
params.push(TagValue {
tag: "startPctVol".to_string(),
value: v.to_string(),
});
}
if let Some(v) = end_pct_vol {
validate_pct_vol("end_pct_vol", v)?;
params.push(TagValue {
tag: "endPctVol".to_string(),
value: v.to_string(),
});
}
if let Some(v) = start_time {
params.push(TagValue {
tag: "startTime".to_string(),
value: v,
});
}
if let Some(v) = end_time {
params.push(TagValue {
tag: "endTime".to_string(),
value: v,
});
}
if let Some(v) = no_take_liq {
params.push(TagValue {
tag: "noTakeLiq".to_string(),
value: v.to_field(),
});
}
Ok(AlgoParams {
strategy: strategy.to_string(),
params,
})
}
#[derive(Debug, Clone, Default)]
pub struct AlgoParams {
pub strategy: String,
pub params: Vec<TagValue>,
}
impl From<String> for AlgoParams {
fn from(strategy: String) -> Self {
Self {
strategy,
params: Vec::new(),
}
}
}
impl From<&str> for AlgoParams {
fn from(strategy: &str) -> Self {
Self {
strategy: strategy.to_string(),
params: Vec::new(),
}
}
}
#[derive(Debug, Clone, Default)]
#[must_use = "VwapBuilder does nothing until you call .build()"]
pub struct VwapBuilder {
max_pct_vol: Option<f64>,
start_time: Option<String>,
end_time: Option<String>,
allow_past_end_time: Option<bool>,
no_take_liq: Option<bool>,
speed_up: Option<bool>,
}
impl VwapBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn max_pct_vol(mut self, pct: f64) -> Self {
self.max_pct_vol = Some(pct);
self
}
pub fn start_time(mut self, time: impl Into<String>) -> Self {
self.start_time = Some(time.into());
self
}
pub fn end_time(mut self, time: impl Into<String>) -> Self {
self.end_time = Some(time.into());
self
}
pub fn allow_past_end_time(mut self, allow: bool) -> Self {
self.allow_past_end_time = Some(allow);
self
}
pub fn no_take_liq(mut self, no_take: bool) -> Self {
self.no_take_liq = Some(no_take);
self
}
pub fn speed_up(mut self, speed_up: bool) -> Self {
self.speed_up = Some(speed_up);
self
}
pub fn build(self) -> Result<AlgoParams, ValidationError> {
let mut params = Vec::new();
if let Some(v) = self.max_pct_vol {
validate_pct_vol("max_pct_vol", v)?;
params.push(TagValue {
tag: "maxPctVol".to_string(),
value: v.to_string(),
});
}
if let Some(v) = self.start_time {
params.push(TagValue {
tag: "startTime".to_string(),
value: v,
});
}
if let Some(v) = self.end_time {
params.push(TagValue {
tag: "endTime".to_string(),
value: v,
});
}
if let Some(v) = self.allow_past_end_time {
params.push(TagValue {
tag: "allowPastEndTime".to_string(),
value: v.to_field(),
});
}
if let Some(v) = self.no_take_liq {
params.push(TagValue {
tag: "noTakeLiq".to_string(),
value: v.to_field(),
});
}
if let Some(v) = self.speed_up {
params.push(TagValue {
tag: "speedUp".to_string(),
value: v.to_field(),
});
}
Ok(AlgoParams {
strategy: "Vwap".to_string(),
params,
})
}
}
#[derive(Debug, Clone, Copy, Default)]
pub enum TwapStrategyType {
#[default]
Marketable,
MatchingMidpoint,
MatchingSameSide,
MatchingLast,
}
impl TwapStrategyType {
fn as_str(&self) -> &'static str {
match self {
TwapStrategyType::Marketable => "Marketable",
TwapStrategyType::MatchingMidpoint => "Matching Midpoint",
TwapStrategyType::MatchingSameSide => "Matching Same Side",
TwapStrategyType::MatchingLast => "Matching Last",
}
}
}
#[derive(Debug, Clone, Default)]
#[must_use = "TwapBuilder does nothing until you call .build()"]
pub struct TwapBuilder {
strategy_type: Option<TwapStrategyType>,
start_time: Option<String>,
end_time: Option<String>,
allow_past_end_time: Option<bool>,
}
impl TwapBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn strategy_type(mut self, strategy: TwapStrategyType) -> Self {
self.strategy_type = Some(strategy);
self
}
pub fn start_time(mut self, time: impl Into<String>) -> Self {
self.start_time = Some(time.into());
self
}
pub fn end_time(mut self, time: impl Into<String>) -> Self {
self.end_time = Some(time.into());
self
}
pub fn allow_past_end_time(mut self, allow: bool) -> Self {
self.allow_past_end_time = Some(allow);
self
}
pub fn build(self) -> Result<AlgoParams, ValidationError> {
let mut params = Vec::new();
if let Some(v) = self.strategy_type {
params.push(TagValue {
tag: "strategyType".to_string(),
value: v.as_str().to_string(),
});
}
if let Some(v) = self.start_time {
params.push(TagValue {
tag: "startTime".to_string(),
value: v,
});
}
if let Some(v) = self.end_time {
params.push(TagValue {
tag: "endTime".to_string(),
value: v,
});
}
if let Some(v) = self.allow_past_end_time {
params.push(TagValue {
tag: "allowPastEndTime".to_string(),
value: v.to_field(),
});
}
Ok(AlgoParams {
strategy: "Twap".to_string(),
params,
})
}
}
#[derive(Debug, Clone, Default)]
#[must_use = "PctVolBuilder does nothing until you call .build()"]
pub struct PctVolBuilder {
pct_vol: Option<f64>,
start_time: Option<String>,
end_time: Option<String>,
no_take_liq: Option<bool>,
}
impl PctVolBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn pct_vol(mut self, pct: f64) -> Self {
self.pct_vol = Some(pct);
self
}
pub fn start_time(mut self, time: impl Into<String>) -> Self {
self.start_time = Some(time.into());
self
}
pub fn end_time(mut self, time: impl Into<String>) -> Self {
self.end_time = Some(time.into());
self
}
pub fn no_take_liq(mut self, no_take: bool) -> Self {
self.no_take_liq = Some(no_take);
self
}
pub fn build(self) -> Result<AlgoParams, ValidationError> {
let mut params = Vec::new();
if let Some(v) = self.pct_vol {
validate_pct_vol("pct_vol", v)?;
params.push(TagValue {
tag: "pctVol".to_string(),
value: v.to_string(),
});
}
if let Some(v) = self.start_time {
params.push(TagValue {
tag: "startTime".to_string(),
value: v,
});
}
if let Some(v) = self.end_time {
params.push(TagValue {
tag: "endTime".to_string(),
value: v,
});
}
if let Some(v) = self.no_take_liq {
params.push(TagValue {
tag: "noTakeLiq".to_string(),
value: v.to_field(),
});
}
Ok(AlgoParams {
strategy: "PctVol".to_string(),
params,
})
}
}
#[derive(Debug, Clone, Copy, Default)]
pub enum RiskAversion {
GetDone,
Aggressive,
#[default]
Neutral,
Passive,
}
impl RiskAversion {
fn as_str(&self) -> &'static str {
match self {
RiskAversion::GetDone => "Get Done",
RiskAversion::Aggressive => "Aggressive",
RiskAversion::Neutral => "Neutral",
RiskAversion::Passive => "Passive",
}
}
}
#[derive(Debug, Clone, Default)]
#[must_use = "ArrivalPriceBuilder does nothing until you call .build()"]
pub struct ArrivalPriceBuilder {
max_pct_vol: Option<f64>,
risk_aversion: Option<RiskAversion>,
start_time: Option<String>,
end_time: Option<String>,
force_completion: Option<bool>,
allow_past_end_time: Option<bool>,
}
impl ArrivalPriceBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn max_pct_vol(mut self, pct: f64) -> Self {
self.max_pct_vol = Some(pct);
self
}
pub fn risk_aversion(mut self, risk: RiskAversion) -> Self {
self.risk_aversion = Some(risk);
self
}
pub fn start_time(mut self, time: impl Into<String>) -> Self {
self.start_time = Some(time.into());
self
}
pub fn end_time(mut self, time: impl Into<String>) -> Self {
self.end_time = Some(time.into());
self
}
pub fn force_completion(mut self, force: bool) -> Self {
self.force_completion = Some(force);
self
}
pub fn allow_past_end_time(mut self, allow: bool) -> Self {
self.allow_past_end_time = Some(allow);
self
}
pub fn build(self) -> Result<AlgoParams, ValidationError> {
let mut params = Vec::new();
if let Some(v) = self.max_pct_vol {
validate_pct_vol("max_pct_vol", v)?;
params.push(TagValue {
tag: "maxPctVol".to_string(),
value: v.to_string(),
});
}
if let Some(v) = self.risk_aversion {
params.push(TagValue {
tag: "riskAversion".to_string(),
value: v.as_str().to_string(),
});
}
if let Some(v) = self.start_time {
params.push(TagValue {
tag: "startTime".to_string(),
value: v,
});
}
if let Some(v) = self.end_time {
params.push(TagValue {
tag: "endTime".to_string(),
value: v,
});
}
if let Some(v) = self.force_completion {
params.push(TagValue {
tag: "forceCompletion".to_string(),
value: v.to_field(),
});
}
if let Some(v) = self.allow_past_end_time {
params.push(TagValue {
tag: "allowPastEndTime".to_string(),
value: v.to_field(),
});
}
Ok(AlgoParams {
strategy: "ArrivalPx".to_string(),
params,
})
}
}
#[derive(Debug, Clone, Copy, Default)]
pub enum AdaptivePriority {
Urgent,
#[default]
Normal,
Patient,
}
impl AdaptivePriority {
fn as_str(&self) -> &'static str {
match self {
AdaptivePriority::Urgent => "Urgent",
AdaptivePriority::Normal => "Normal",
AdaptivePriority::Patient => "Patient",
}
}
}
#[derive(Debug, Clone, Default)]
#[must_use = "AdaptiveBuilder does nothing until you call .build()"]
pub struct AdaptiveBuilder {
priority: Option<AdaptivePriority>,
}
impl AdaptiveBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn priority(mut self, priority: AdaptivePriority) -> Self {
self.priority = Some(priority);
self
}
pub fn build(self) -> Result<AlgoParams, ValidationError> {
let mut params = Vec::new();
if let Some(v) = self.priority {
params.push(TagValue {
tag: "adaptivePriority".to_string(),
value: v.as_str().to_string(),
});
}
Ok(AlgoParams {
strategy: "Adaptive".to_string(),
params,
})
}
}
#[derive(Debug, Clone, Default)]
#[must_use = "ClosePriceBuilder does nothing until you call .build()"]
pub struct ClosePriceBuilder {
max_pct_vol: Option<f64>,
risk_aversion: Option<RiskAversion>,
start_time: Option<String>,
force_completion: Option<bool>,
}
impl ClosePriceBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn max_pct_vol(mut self, pct: f64) -> Self {
self.max_pct_vol = Some(pct);
self
}
pub fn risk_aversion(mut self, risk: RiskAversion) -> Self {
self.risk_aversion = Some(risk);
self
}
pub fn start_time(mut self, time: impl Into<String>) -> Self {
self.start_time = Some(time.into());
self
}
pub fn force_completion(mut self, force: bool) -> Self {
self.force_completion = Some(force);
self
}
pub fn build(self) -> Result<AlgoParams, ValidationError> {
let mut params = Vec::new();
if let Some(v) = self.max_pct_vol {
validate_pct_vol("max_pct_vol", v)?;
params.push(TagValue {
tag: "maxPctVol".to_string(),
value: v.to_string(),
});
}
if let Some(v) = self.risk_aversion {
params.push(TagValue {
tag: "riskAversion".to_string(),
value: v.as_str().to_string(),
});
}
if let Some(v) = self.start_time {
params.push(TagValue {
tag: "startTime".to_string(),
value: v,
});
}
if let Some(v) = self.force_completion {
params.push(TagValue {
tag: "forceCompletion".to_string(),
value: v.to_field(),
});
}
Ok(AlgoParams {
strategy: "ClosePx".to_string(),
params,
})
}
}
#[derive(Debug, Clone, Default)]
#[must_use = "DarkIceBuilder does nothing until you call .build()"]
pub struct DarkIceBuilder {
display_size: Option<i32>,
start_time: Option<String>,
end_time: Option<String>,
allow_past_end_time: Option<bool>,
}
impl DarkIceBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn display_size(mut self, size: i32) -> Self {
self.display_size = Some(size);
self
}
pub fn start_time(mut self, time: impl Into<String>) -> Self {
self.start_time = Some(time.into());
self
}
pub fn end_time(mut self, time: impl Into<String>) -> Self {
self.end_time = Some(time.into());
self
}
pub fn allow_past_end_time(mut self, allow: bool) -> Self {
self.allow_past_end_time = Some(allow);
self
}
pub fn build(self) -> Result<AlgoParams, ValidationError> {
let mut params = Vec::new();
if let Some(v) = self.display_size {
params.push(TagValue {
tag: "displaySize".to_string(),
value: v.to_string(),
});
}
if let Some(v) = self.start_time {
params.push(TagValue {
tag: "startTime".to_string(),
value: v,
});
}
if let Some(v) = self.end_time {
params.push(TagValue {
tag: "endTime".to_string(),
value: v,
});
}
if let Some(v) = self.allow_past_end_time {
params.push(TagValue {
tag: "allowPastEndTime".to_string(),
value: v.to_field(),
});
}
Ok(AlgoParams {
strategy: "DarkIce".to_string(),
params,
})
}
}
#[derive(Debug, Clone, Default)]
#[must_use = "AccumulateDistributeBuilder does nothing until you call .build()"]
pub struct AccumulateDistributeBuilder {
component_size: Option<i32>,
time_between_orders: Option<i32>,
randomize_time_20: Option<bool>,
randomize_size_55: Option<bool>,
give_up: Option<i32>,
catch_up: Option<bool>,
wait_for_fill: Option<bool>,
active_time_start: Option<String>,
active_time_end: Option<String>,
}
impl AccumulateDistributeBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn component_size(mut self, size: i32) -> Self {
self.component_size = Some(size);
self
}
pub fn time_between_orders(mut self, seconds: i32) -> Self {
self.time_between_orders = Some(seconds);
self
}
pub fn randomize_time_20(mut self, randomize: bool) -> Self {
self.randomize_time_20 = Some(randomize);
self
}
pub fn randomize_size_55(mut self, randomize: bool) -> Self {
self.randomize_size_55 = Some(randomize);
self
}
pub fn give_up(mut self, give_up: i32) -> Self {
self.give_up = Some(give_up);
self
}
pub fn catch_up(mut self, catch_up: bool) -> Self {
self.catch_up = Some(catch_up);
self
}
pub fn wait_for_fill(mut self, wait: bool) -> Self {
self.wait_for_fill = Some(wait);
self
}
pub fn active_time_start(mut self, time: impl Into<String>) -> Self {
self.active_time_start = Some(time.into());
self
}
pub fn active_time_end(mut self, time: impl Into<String>) -> Self {
self.active_time_end = Some(time.into());
self
}
pub fn build(self) -> Result<AlgoParams, ValidationError> {
let mut params = Vec::new();
if let Some(v) = self.component_size {
params.push(TagValue {
tag: "componentSize".to_string(),
value: v.to_string(),
});
}
if let Some(v) = self.time_between_orders {
params.push(TagValue {
tag: "timeBetweenOrders".to_string(),
value: v.to_string(),
});
}
if let Some(v) = self.randomize_time_20 {
params.push(TagValue {
tag: "randomizeTime20".to_string(),
value: v.to_field(),
});
}
if let Some(v) = self.randomize_size_55 {
params.push(TagValue {
tag: "randomizeSize55".to_string(),
value: v.to_field(),
});
}
if let Some(v) = self.give_up {
params.push(TagValue {
tag: "giveUp".to_string(),
value: v.to_string(),
});
}
if let Some(v) = self.catch_up {
params.push(TagValue {
tag: "catchUp".to_string(),
value: v.to_field(),
});
}
if let Some(v) = self.wait_for_fill {
params.push(TagValue {
tag: "waitForFill".to_string(),
value: v.to_field(),
});
}
if let Some(v) = self.active_time_start {
params.push(TagValue {
tag: "activeTimeStart".to_string(),
value: v,
});
}
if let Some(v) = self.active_time_end {
params.push(TagValue {
tag: "activeTimeEnd".to_string(),
value: v,
});
}
Ok(AlgoParams {
strategy: "AD".to_string(),
params,
})
}
}
#[derive(Debug, Clone, Default)]
#[must_use = "BalanceImpactRiskBuilder does nothing until you call .build()"]
pub struct BalanceImpactRiskBuilder {
max_pct_vol: Option<f64>,
risk_aversion: Option<RiskAversion>,
force_completion: Option<bool>,
}
impl BalanceImpactRiskBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn max_pct_vol(mut self, pct: f64) -> Self {
self.max_pct_vol = Some(pct);
self
}
pub fn risk_aversion(mut self, risk: RiskAversion) -> Self {
self.risk_aversion = Some(risk);
self
}
pub fn force_completion(mut self, force: bool) -> Self {
self.force_completion = Some(force);
self
}
pub fn build(self) -> Result<AlgoParams, ValidationError> {
let mut params = Vec::new();
if let Some(v) = self.max_pct_vol {
validate_pct_vol("max_pct_vol", v)?;
params.push(TagValue {
tag: "maxPctVol".to_string(),
value: v.to_string(),
});
}
if let Some(v) = self.risk_aversion {
params.push(TagValue {
tag: "riskAversion".to_string(),
value: v.as_str().to_string(),
});
}
if let Some(v) = self.force_completion {
params.push(TagValue {
tag: "forceCompletion".to_string(),
value: v.to_field(),
});
}
Ok(AlgoParams {
strategy: "BalanceImpactRisk".to_string(),
params,
})
}
}
#[derive(Debug, Clone, Default)]
#[must_use = "MinimiseImpactBuilder does nothing until you call .build()"]
pub struct MinimiseImpactBuilder {
max_pct_vol: Option<f64>,
}
impl MinimiseImpactBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn max_pct_vol(mut self, pct: f64) -> Self {
self.max_pct_vol = Some(pct);
self
}
pub fn build(self) -> Result<AlgoParams, ValidationError> {
let mut params = Vec::new();
if let Some(v) = self.max_pct_vol {
validate_pct_vol("max_pct_vol", v)?;
params.push(TagValue {
tag: "maxPctVol".to_string(),
value: v.to_string(),
});
}
Ok(AlgoParams {
strategy: "MinImpact".to_string(),
params,
})
}
}
#[derive(Debug, Clone, Default)]
#[must_use = "PctVolPriceBuilder does nothing until you call .build()"]
pub struct PctVolPriceBuilder {
pct_vol: Option<f64>,
delta_pct_vol: Option<f64>,
min_pct_vol_4_px: Option<f64>,
max_pct_vol_4_px: Option<f64>,
start_time: Option<String>,
end_time: Option<String>,
no_take_liq: Option<bool>,
}
impl PctVolPriceBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn pct_vol(mut self, pct: f64) -> Self {
self.pct_vol = Some(pct);
self
}
pub fn delta_pct_vol(mut self, delta: f64) -> Self {
self.delta_pct_vol = Some(delta);
self
}
pub fn min_pct_vol_4_px(mut self, pct: f64) -> Self {
self.min_pct_vol_4_px = Some(pct);
self
}
pub fn max_pct_vol_4_px(mut self, pct: f64) -> Self {
self.max_pct_vol_4_px = Some(pct);
self
}
pub fn start_time(mut self, time: impl Into<String>) -> Self {
self.start_time = Some(time.into());
self
}
pub fn end_time(mut self, time: impl Into<String>) -> Self {
self.end_time = Some(time.into());
self
}
pub fn no_take_liq(mut self, no_take: bool) -> Self {
self.no_take_liq = Some(no_take);
self
}
pub fn build(self) -> Result<AlgoParams, ValidationError> {
let mut params = Vec::new();
if let Some(v) = self.pct_vol {
validate_pct_vol("pct_vol", v)?;
params.push(TagValue {
tag: "pctVol".to_string(),
value: v.to_string(),
});
}
if let Some(v) = self.delta_pct_vol {
validate_pct_vol("delta_pct_vol", v)?;
params.push(TagValue {
tag: "deltaPctVol".to_string(),
value: v.to_string(),
});
}
if let Some(v) = self.min_pct_vol_4_px {
validate_pct_vol("min_pct_vol_4_px", v)?;
params.push(TagValue {
tag: "minPctVol4Px".to_string(),
value: v.to_string(),
});
}
if let Some(v) = self.max_pct_vol_4_px {
validate_pct_vol("max_pct_vol_4_px", v)?;
params.push(TagValue {
tag: "maxPctVol4Px".to_string(),
value: v.to_string(),
});
}
if let Some(v) = self.start_time {
params.push(TagValue {
tag: "startTime".to_string(),
value: v,
});
}
if let Some(v) = self.end_time {
params.push(TagValue {
tag: "endTime".to_string(),
value: v,
});
}
if let Some(v) = self.no_take_liq {
params.push(TagValue {
tag: "noTakeLiq".to_string(),
value: v.to_field(),
});
}
Ok(AlgoParams {
strategy: "PctVolPx".to_string(),
params,
})
}
}
#[derive(Debug, Clone, Default)]
#[must_use = "PctVolSizeBuilder does nothing until you call .build()"]
pub struct PctVolSizeBuilder {
start_pct_vol: Option<f64>,
end_pct_vol: Option<f64>,
start_time: Option<String>,
end_time: Option<String>,
no_take_liq: Option<bool>,
}
impl PctVolSizeBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn start_pct_vol(mut self, pct: f64) -> Self {
self.start_pct_vol = Some(pct);
self
}
pub fn end_pct_vol(mut self, pct: f64) -> Self {
self.end_pct_vol = Some(pct);
self
}
pub fn start_time(mut self, time: impl Into<String>) -> Self {
self.start_time = Some(time.into());
self
}
pub fn end_time(mut self, time: impl Into<String>) -> Self {
self.end_time = Some(time.into());
self
}
pub fn no_take_liq(mut self, no_take: bool) -> Self {
self.no_take_liq = Some(no_take);
self
}
pub fn build(self) -> Result<AlgoParams, ValidationError> {
build_windowed_pct_vol(
"PctVolSz",
self.start_pct_vol,
self.end_pct_vol,
self.start_time,
self.end_time,
self.no_take_liq,
)
}
}
#[derive(Debug, Clone, Default)]
#[must_use = "PctVolTimeBuilder does nothing until you call .build()"]
pub struct PctVolTimeBuilder {
start_pct_vol: Option<f64>,
end_pct_vol: Option<f64>,
start_time: Option<String>,
end_time: Option<String>,
no_take_liq: Option<bool>,
}
impl PctVolTimeBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn start_pct_vol(mut self, pct: f64) -> Self {
self.start_pct_vol = Some(pct);
self
}
pub fn end_pct_vol(mut self, pct: f64) -> Self {
self.end_pct_vol = Some(pct);
self
}
pub fn start_time(mut self, time: impl Into<String>) -> Self {
self.start_time = Some(time.into());
self
}
pub fn end_time(mut self, time: impl Into<String>) -> Self {
self.end_time = Some(time.into());
self
}
pub fn no_take_liq(mut self, no_take: bool) -> Self {
self.no_take_liq = Some(no_take);
self
}
pub fn build(self) -> Result<AlgoParams, ValidationError> {
build_windowed_pct_vol(
"PctVolTm",
self.start_pct_vol,
self.end_pct_vol,
self.start_time,
self.end_time,
self.no_take_liq,
)
}
}
#[derive(Debug, Clone, Default)]
#[must_use = "AccuDistrBuilder does nothing until you call .build()"]
pub struct AccuDistrBuilder {
time_between_orders: Option<i32>,
route_order_type: Option<String>,
component_size: Option<i32>,
active_time_start: Option<String>,
active_time_end: Option<String>,
active_time_tz: Option<String>,
}
impl AccuDistrBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn time_between_orders(mut self, seconds: i32) -> Self {
self.time_between_orders = Some(seconds);
self
}
pub fn route_order_type(mut self, order_type: impl Into<String>) -> Self {
self.route_order_type = Some(order_type.into());
self
}
pub fn component_size(mut self, size: i32) -> Self {
self.component_size = Some(size);
self
}
pub fn active_time_start(mut self, time: impl Into<String>) -> Self {
self.active_time_start = Some(time.into());
self
}
pub fn active_time_end(mut self, time: impl Into<String>) -> Self {
self.active_time_end = Some(time.into());
self
}
pub fn active_time_tz(mut self, tz: impl Into<String>) -> Self {
self.active_time_tz = Some(tz.into());
self
}
pub fn build(self) -> Result<AlgoParams, ValidationError> {
let mut params = Vec::new();
if let Some(v) = self.time_between_orders {
params.push(TagValue {
tag: "timeBetweenOrders".to_string(),
value: v.to_string(),
});
}
if let Some(v) = self.route_order_type {
params.push(TagValue {
tag: "routeOrderType".to_string(),
value: v,
});
}
if let Some(v) = self.component_size {
params.push(TagValue {
tag: "componentSize".to_string(),
value: v.to_string(),
});
}
if let Some(v) = self.active_time_start {
params.push(TagValue {
tag: "activeTimeStart".to_string(),
value: v,
});
}
if let Some(v) = self.active_time_end {
params.push(TagValue {
tag: "activeTimeEnd".to_string(),
value: v,
});
}
if let Some(v) = self.active_time_tz {
params.push(TagValue {
tag: "activeTimeTz".to_string(),
value: v,
});
}
Ok(AlgoParams {
strategy: "AccuDistr".to_string(),
params,
})
}
}
#[cfg(test)]
#[path = "algo_builders_tests.rs"]
mod tests;