Labeling Price Moves That Overcome the Bid–Ask Spread
Summary
The document discusses a high-frequency machine-learning target designed to distinguish price changes large enough to overcome transaction costs from smaller mid-price movements. A rise in the mid-price alone may still lose money if a trader buys at the ask and later sells at the bid. The proposed framing treats such insufficient moves as no actionable movement, even when the price did change.
The question presents a rolling-average labeling example, then asks how to incorporate best bid and ask prices. The response offers a general threshold principle: require the expected signal to exceed the half-spread when crossing it to trade. This is guidance, not a complete labeling algorithm. It does not specify forecast horizon, fees, slippage, queue position, or a robust validation method, all of which affect whether a signal remains profitable after execution costs.
Key ideas
- Mid-price direction alone does not establish that a trade can overcome the bid–ask spread.
- A useful classification target can label only price moves that exceed the relevant spread cost.
- A no-movement label can include small price changes that are not actionable after costs.
- The response recommends requiring expected signal strength to exceed the half-spread.
- A complete strategy must account for execution effects and other costs beyond the simplified threshold.
Tags
Full text
# Crossing the spread as a ML signal
# Crossing the spread as a ML signal
In the optic of high-frequency trading, most of the standard trading algorithms work on the principle of mid-price prediction or mid-price movement prediction. However a big drawback of this technique can be seen on the following picture. Clearly in case 1, there is an increase in the mid-price of the product, but since we need to enter the market at the ask price and exit at the bid price, we are actually incurring a loss in this transaction. In case 2, the movement of the price is large enough to cover the bid-ask spread and thus is a profitable transaction.
We have however diverted from this traditional approach and instead focused on predicting only those price movements which are substantial enough to cross the bid-ask spread. It is important to understand that since we only consider change in price that cross the bid-ask spread as a ”movement”, which would certainly generate profit, predicting ”no movement” does not mean that there was absolutely no movement in the price of the product. It just means that the movement was not substantial enough to cross the spread and thus was as useless for our model as no actual movement in the price.
I understand well that principle, but it is way difference how to code it in python considering the best bid, the best ask and the mid-price.
How do I find a signal, that is strong enough to overcome the spread cost? Is there a way that principle to be coded as a function in python?
UPDATE
My actual labelling strategy is this one, but it represents the case 1 of the above picture.
```
def label(true_values):
alpha = 0.00013
walk_steps = 10
labels = [0 for _ in range(walk_steps)]
for k in range(walk_steps, len(true_values)):
prev_vals = np.mean(true_values[k - walk_steps:k + 1])
next_vals = np.mean(true_values[k:k + walk_steps + 1])
pred_prev_vals = np.mean(true_values[k - walk_steps:k + 1])
true_label = 0
if prev_vals > next_vals * (1.0 + alpha):
true_label = 1
elif prev_vals < next_vals * (1.0 - alpha):
true_label = -1
labels.append(true_label)
return labels
```
It can be more accurate to get a labelling strategy that can tell "Ok, if the midprice cross the spread, then I'll place a label 1 or -1 depending if it is going up or down and placing a label 0 otherwise."
We can build the code in considering the `bidprice` and `askprice` as variables.
## Answer by Ezy (score 1)
https://quant.stackexchange.com/a/43171
In practice you try to cross the half-spread when your signal is bigger than half-spread so your goal is to find a stable signal that is bigger than half-spread in expectation.Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.