feat: evaluate trading buy filters into decision-scoped constraints
This commit is contained in:
@@ -988,6 +988,18 @@ pub struct StrategyDecision {
|
||||
}
|
||||
|
||||
impl StrategyDecision {
|
||||
pub fn potential_buy_symbols(&self, open_orders: &[OpenOrderView]) -> BTreeSet<String> {
|
||||
let mut symbols = BTreeSet::new();
|
||||
if self.rebalance {
|
||||
symbols.extend(self.target_weights.iter().filter(|(_, weight)| **weight > 0.0).map(|(symbol, _)| symbol.clone()));
|
||||
}
|
||||
for intent in &self.order_intents {
|
||||
intent.collect_potential_buy_symbols(open_orders, &mut symbols);
|
||||
}
|
||||
symbols.retain(|symbol| !symbol.trim().is_empty());
|
||||
symbols
|
||||
}
|
||||
|
||||
pub fn merge_from(&mut self, mut other: StrategyDecision) {
|
||||
self.buy_denials.append(&mut other.buy_denials);
|
||||
self.rebalance |= other.rebalance;
|
||||
@@ -1217,6 +1229,42 @@ pub enum OrderIntent {
|
||||
}
|
||||
|
||||
impl OrderIntent {
|
||||
fn collect_potential_buy_symbols(&self, open_orders: &[OpenOrderView], symbols: &mut BTreeSet<String>) {
|
||||
match self.unwrapped() {
|
||||
Self::Shares { symbol, quantity, .. } | Self::LimitShares { symbol, quantity, .. } if *quantity > 0 => { symbols.insert(symbol.clone()); }
|
||||
Self::Lots { symbol, lots, .. } | Self::LimitLots { symbol, lots, .. } if *lots > 0 => { symbols.insert(symbol.clone()); }
|
||||
Self::TargetShares { symbol, target_quantity, .. } | Self::LimitTargetShares { symbol, target_quantity, .. } if *target_quantity > 0 => { symbols.insert(symbol.clone()); }
|
||||
Self::Value { symbol, value, .. } | Self::LimitValue { symbol, value, .. } | Self::AlgoValue { symbol, value, .. } if *value > 0.0 => { symbols.insert(symbol.clone()); }
|
||||
Self::Percent { symbol, percent, .. } | Self::LimitPercent { symbol, percent, .. } | Self::AlgoPercent { symbol, percent, .. } if *percent > 0.0 => { symbols.insert(symbol.clone()); }
|
||||
Self::TargetValue { symbol, target_value, .. } | Self::LimitTargetValue { symbol, target_value, .. } | Self::TimedTargetValue { symbol, target_value, .. } if *target_value > 0.0 => { symbols.insert(symbol.clone()); }
|
||||
Self::TargetPercent { symbol, target_percent, .. } | Self::LimitTargetPercent { symbol, target_percent, .. } if *target_percent > 0.0 => { symbols.insert(symbol.clone()); }
|
||||
Self::TargetPortfolioSmart { target_weights, .. } => {
|
||||
symbols.extend(target_weights.iter().filter(|(_, weight)| **weight > 0.0).map(|(symbol, _)| symbol.clone()));
|
||||
}
|
||||
Self::ModifyOrder { order_id, new_total_quantity, new_limit_price, .. } => {
|
||||
if let Some(order) = open_orders.iter().find(|order| order.order_id == *order_id)
|
||||
&& order.side == OrderSide::Buy
|
||||
&& (new_total_quantity.is_some_and(|value| value > order.requested_quantity)
|
||||
|| new_limit_price.is_some_and(|value| value > order.limit_price))
|
||||
{
|
||||
symbols.insert(order.symbol.clone());
|
||||
}
|
||||
}
|
||||
Self::Shares { .. } | Self::LimitShares { .. }
|
||||
| Self::Lots { .. } | Self::LimitLots { .. }
|
||||
| Self::TargetShares { .. } | Self::LimitTargetShares { .. }
|
||||
| Self::Value { .. } | Self::LimitValue { .. } | Self::AlgoValue { .. }
|
||||
| Self::Percent { .. } | Self::LimitPercent { .. } | Self::AlgoPercent { .. }
|
||||
| Self::TargetValue { .. } | Self::LimitTargetValue { .. } | Self::TimedTargetValue { .. }
|
||||
| Self::TargetPercent { .. } | Self::LimitTargetPercent { .. }
|
||||
| Self::CancelOrder { .. } | Self::CancelSymbol { .. } | Self::CancelAll { .. }
|
||||
| Self::UpdateUniverse { .. } | Self::Subscribe { .. } | Self::Unsubscribe { .. }
|
||||
| Self::DepositWithdraw { .. } | Self::FinanceRepay { .. } | Self::SetManagementFeeRate { .. }
|
||||
| Self::Futures { .. } => {}
|
||||
Self::WithTimeInForce { .. } => unreachable!("intent is unwrapped"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_time_in_force(self, time_in_force: OrderTimeInForce) -> Self {
|
||||
match self {
|
||||
Self::WithTimeInForce { intent, .. } => Self::WithTimeInForce {
|
||||
|
||||
Reference in New Issue
Block a user