Use snapshot last price for jq intraday execution

This commit is contained in:
boris
2026-04-21 18:35:02 -07:00
parent c67932a2c9
commit 5be836423a
2 changed files with 55 additions and 25 deletions

View File

@@ -121,10 +121,8 @@ where
if self.execution_price_field == PriceField::Last
&& self.intraday_execution_start_time.is_some()
{
return match side {
OrderSide::Buy => self.buy_price(snapshot),
OrderSide::Sell => self.sell_price(snapshot),
};
let _ = side;
return snapshot.price(PriceField::Last);
}
match side {
@@ -1079,23 +1077,6 @@ where
return None;
}
let start_cursor = self
.intraday_execution_start_time
.map(|start_time| date.and_time(start_time));
let quotes = data.execution_quotes_on(date, symbol);
if let Some(fill) = self.select_execution_fill(
quotes,
side,
start_cursor,
requested_qty,
round_lot,
cash_limit,
gross_limit,
) {
return Some(fill);
}
if self.intraday_execution_start_time.is_some() {
let execution_price = self.snapshot_execution_price(snapshot, side);
let quantity = match side {
@@ -1122,6 +1103,23 @@ where
});
}
let start_cursor = self
.intraday_execution_start_time
.map(|start_time| date.and_time(start_time));
let quotes = data.execution_quotes_on(date, symbol);
if let Some(fill) = self.select_execution_fill(
quotes,
side,
start_cursor,
requested_qty,
round_lot,
cash_limit,
gross_limit,
) {
return Some(fill);
}
None
}

View File

@@ -593,10 +593,8 @@ impl JqMicroCapStrategy {
market: &crate::data::DailyMarketSnapshot,
side: OrderSide,
) -> f64 {
match side {
OrderSide::Buy => market.buy_price(PriceField::Last),
OrderSide::Sell => market.sell_price(PriceField::Last),
}
let _ = side;
market.price(PriceField::Last)
}
fn project_order_value(
@@ -814,6 +812,40 @@ impl JqMicroCapStrategy {
return None;
}
if let Some(market) = ctx.data.market(date, symbol) {
let execution_price = self.projected_execution_price(market, side);
if execution_price.is_finite() && execution_price > 0.0 {
let quantity = match side {
OrderSide::Buy => {
let cash = cash_limit.unwrap_or(f64::INFINITY);
let mut take_qty = self.round_lot_quantity(requested_qty, round_lot.max(1));
while take_qty > 0 {
let candidate_gross = execution_price * take_qty as f64;
if gross_limit.is_some_and(|limit| candidate_gross > limit + 1e-6) {
take_qty = take_qty.saturating_sub(round_lot.max(1));
continue;
}
if candidate_gross <= cash + 1e-6 {
break;
}
take_qty = take_qty.saturating_sub(round_lot.max(1));
}
take_qty
}
OrderSide::Sell => requested_qty,
};
if quantity > 0 {
let next_cursor = date.and_time(self.intraday_execution_start_time())
+ Duration::seconds(1);
return Some(ProjectedExecutionFill {
price: execution_price,
quantity,
next_cursor,
});
}
}
}
let lot = round_lot.max(1);
let start_cursor = self.projected_execution_start_cursor(date, symbol, execution_state);
let quotes = ctx.data.execution_quotes_on(date, symbol);