Tips for doing financial analysis with OHLC bar data.
Many of you doing quanty analysis with OHLC bar data.
Here's some boring but crucial stuff you need to understand if you're doing that. 👇👇👇
1/n
An OHLC bar represents a summary of trades that happened in a certain period.
Open -the price of the first trade in the period
High - the highest price traded in the period
Low - the lowest price traded in the period
Close - the price of the final trade in the period
2/n
For daily stock data, the Close price will be the price arrived at in the closing auction.
This is set by balancing the supply and demand of MOO (market on close) and LOO (limit on close) orders to maximize the amount of stock traded.
3/n
Which of these 4 prices can you actually trade at?
To understand this you must understand that a trade happens when an aggressive order meets a passive order.
(Well acktually.... sometimes two aggressive orders collide, but that's rare)
4/n
You look at the limit order book (LOB) of an asset and you can see bids to buy the asset at $99 and offers to sell it at $101.
We say the "midpoint" is in the middle at $100
On a market order or "marketable limit order" you can *immediately*:
- Buy at $101
- Sell at $99
5/n
The moment you aggressively trade you're showing an unrealized loss (marked against midpoint) of -$1 (difference between BBO and midpoint)
The person you traded with (probably a market maker) is showing an unrealized profit of +$1.
This is the price of immediacy.
6/n
Would we say this trade changed the "price" of the asset?
Depends what we mean...
If our trade was an aggressive buy at $101 and the previous trade was an aggressive sell at $99, then the "last trade price" will have changed.
But the midpoint will have stayed the same.
7/n
How does this relate to bar data?
Well... imagine that Best Bid and Best Offer didn't change at all in our period...
Aggressive sellers were trading at $99.
Aggressive buyers were trading at $101.
These trades get aggregated into our OHLC bars
8/n
The high of our bar is going to be $101
The low is going to be $99.
The open and close are going to be either $99 or $101 depending on whether the first and last trades were aggressive buys or sells.
You can probably see the problem.
9/n
We know we could buy at the high of the bar
We know we could sell at the low of the bar
We don't know if we could buy or sell at the open or close.
(If it's relatively big, it's unlikely we could have sold there. If it's relatively small, it's unlikely we could buy.)
10/n
This is why the mean-reversion strategy you backtested on the close of 1-minute EURUSD bars looks so good.
It's just a sampling artifact caused by the fact that a high close is likely to be an aggressive buy and a low close is likely to be an aggressive sell.
11/n
How do you control for this?
One way is to do your analysis off of an estimate of the average price during the bar, rather than the close.
Simply taking the mean of the OHL and C prices will be better than doing your analysis off of the close sequence.
12/n
An alternative (and better) way to filter prices is a TWAP estimate that assumes that prices drift between the OHLC points and OLHC points at a constant rate.
This is a good estimation of the price you'd expect with a TWAP execution algo set to complete by the bar close.
13/n
Here's some longhand dplyr (R) code to illustrate:
The TWAP series represents a reasonably filtered price series for you to analyze.
Use a filtered price like this rather than the snapshot open or close, otherwise, you'll introduce unwanted bid/ask bounce effects.
14/n
An exception here is the closing auction price on daily OHLC stock data.
If your trading is a small proportion of the average auction volume, you can relatively safely assume you could, in fact, trade at the Close point in your data.
15/n
HOWEVER, be aware that you can't observe the close and act on it.
This is true because:
- the stimulus/response gap means you can't do that with anything in the universe anyway
- To participate in the closing auction you need to enter orders 15 mins before close.
16/n
So assume all things you're analyzing are things you could have known at the time you are simulating acting.
And use filtered prices, rather than snapshot prices, to remove bid/ask bounce artifacts.
17/17 Fin.
• • •
Missing some Tweet in this thread? You can try to
force a refresh
It's easy to lose money trading if you:
1. Trade too much (paying fees + impact on each txn)
2. Size positions too big (high vol hurts compounding ability + gets u rekt)
3. Shorting positive drift/risk premia
It's hard to lose money consistently if you avoid these things.
However clueless you are, you get to trade at market prices.
Imagine we can know that an asset has a fair value of $100.
You might think it's worth $150.
But if it's quoted $99 / $101, you can buy now at $101.
You were totally wrong but you still bought close to fair value.
The same mechanisms that make it hard to get an edge also make it hard for you to trade at really bad prices.
In a simple model, you might say that prices are set by:
- (risky) arbitrage and relative value in the short term
- pricing/valuation models in the long term