Let’s build a market profile chart using Python in about 30 lines of code. This is a bare version of J.P Steidlmayer’s charting system, but should give you a good idea of market distribution within a particular time frame and where the market spent most of its time. Here we’ll focus on monthly distributions using end-of-day data from Yahoo Finance.
Yahoo's ichart service is down. You'll need to use Google Finance instead - source code at end of blog has been udpdated.
So, what is Market Profile?
A Market Profile is an intra-day charting technique (price vertical, time/activity horizontal) devised by J. Peter Steidlmayer, a trader at the Chicago Board of Trade (CBOT), ca 1959-1985. Steidlmayer was seeking to evaluate market value as it developed in the day time frame. Steidlmayer’s charts displayed a bell shape, fatter at the middle prices, with activity trailing off at the higher and lower prices. In this structure he recognized the ‘Normal’, gaussian distribution he had met with in college statistics… (Wikipedia: Market Profile)
J.P Steidlmayer would record intra-day pit action using a sideways distribution plot. This would give him insight as to where price spent the most time and where it struggled. In a lot of cases, the chart would form a normal distribution. Armed with this information along with visual and audible cues from floor traders, he could easily figure out when markets were stretched and how far the price would retract with high probability. And if the pits got excited around the distribution tails, he would stick it out assuming that new information came in and could potentially shake things up.
Today, unfortunately, there really isn’t any pit trading left to yield cues, but this is still a great way of looking at the market, better, or at least just as good as line or candlestick charts. Maybe in another video we’ll look at building an ‘excitement’ indicator to capture unusual market speed changes, price jumps, abrupt volume changes, etc. In the Market Profile we will build here, we will capture a year’s worth of trading using monthly profiles and daily letters.
Keep in mind that markets are not always well behaved or normally distributed. They can break out of a pattern without any warning at the beginning, end, or anywhere in the middle of the month, and at the start, end, or anytime in a trading day. Beware!
Brief Look at the Code
Let’s look at the important components of the Market Profile code (for more details see the YouTube video). The
Print_Market_Profile takes 5 parameters: the symbol you want to visualize, the height precision (or dollar precision), the time-frame frequency, and the market start and end date.
The market data is downloaded from Yahoo Finance using the
fin_prod_data = pdr.get_data_yahoo(symbol.upper(), start_date, end_date)
In : fin_prod_data.head()
Open High Low Close Volume \
2016-04-01 116.080002 116.980003 115.550003 116.930000 10405400
2016-04-04 116.669998 116.730003 116.070000 116.150002 7643700
2016-04-05 117.760002 117.930000 117.150002 117.660004 8865900
2016-04-06 116.699997 117.389999 116.260002 116.940002 7549400
2016-04-07 118.650002 118.849998 115.000000 118.610001 11900500
In order to scale the height of our chart, we multiply the high and low price with the
variable then round those values. The function defaults to dollar amounts, dropping everything after the decimal point. If a stock is trading in the $10 range, you will need to use a
larger than one, and for a stock trading in the 100s, a
smaller than one.
How Many Profiles to Display?
We use Pandas’
TimeGrouper function to extract the end dates for each profile to know when to stop building a current profile and move on to the next.
time_groups = fin_prod_data.groupby(pd.TimeGrouper(freq=frequency))['Adj Close'].mean()
In : time_groups
Freq: M, Name: Adj Close, dtype: float64